Skip to content

Commit

Permalink
Merge branch 'ccip-develop' into fix/onramp-allowlist-race-condition
Browse files Browse the repository at this point in the history
  • Loading branch information
0xsuryansh authored Oct 8, 2024
2 parents 6b592cb + c4907f3 commit 1f26f49
Show file tree
Hide file tree
Showing 10 changed files with 2,995 additions and 6 deletions.
5 changes: 4 additions & 1 deletion contracts/gas-snapshots/ccip.gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ BurnMintTokenPool_releaseOrMint:test_PoolMint_Success() (gas: 112391)
BurnWithFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28842)
BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55271)
BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 244050)
BurnWithFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 24170)
BurnWithFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 24168)
BurnWithFromMintTokenPool_releaseOrMint:test_Setup_Success() (gas: 24547)
BurnWithFromMintTokenPool_releaseOrMint:test_releaseOrMint_NegativeMintAmount_reverts() (gas: 93840)
BurnWithFromMintTokenPool_releaseOrMint:test_releaseOrMint_Success() (gas: 93423)
CCIPClientExample_sanity:test_ImmutableExamples_Success() (gas: 2052431)
CCIPHome__validateConfig:test__validateConfigLessTransmittersThanSigners_Success() (gas: 334693)
CCIPHome__validateConfig:test__validateConfigSmallerFChain_Success() (gas: 466117)
Expand Down
1 change: 1 addition & 0 deletions contracts/scripts/native_solc_compile_all_ccip
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ compileContract ccip/pools/BurnWithFromMintTokenPool.sol
compileContract ccip/pools/LockReleaseTokenPoolAndProxy.sol
compileContract ccip/pools/BurnMintTokenPoolAndProxy.sol
compileContract ccip/pools/BurnWithFromMintTokenPoolAndProxy.sol
compileContract ccip/pools/BurnWithFromMintRebasingTokenPool.sol
compileContract ccip/pools/TokenPool.sol


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.24;

import {IBurnMintERC20} from "../../shared/token/ERC20/IBurnMintERC20.sol";

import {Pool} from "../libraries/Pool.sol";
import {BurnWithFromMintTokenPool} from "./BurnWithFromMintTokenPool.sol";

/// @notice This pool mints and burns a 3rd-party token.
/// @dev This contract is a variant of BurnMintTokenPool that uses `burn(from, amount)`.
/// @dev This contract supports minting tokens that do not mint the exact amount they are asked to mint. This can be
/// used for rebasing tokens. NOTE: for true rebasing support, the lockOrBurn method must also be updated to support
/// relaying the correct amount.
contract BurnWithFromMintRebasingTokenPool is BurnWithFromMintTokenPool {
error NegativeMintAmount(uint256 amountBurned);

string public constant override typeAndVersion = "BurnWithFromMintRebasingTokenPool 1.5.0";

constructor(
IBurnMintERC20 token,
address[] memory allowlist,
address rmnProxy,
address router
) BurnWithFromMintTokenPool(token, allowlist, rmnProxy, router) {}

/// @notice Mint tokens from the pool to the recipient
/// @dev The _validateReleaseOrMint check is an essential security check
function releaseOrMint(
Pool.ReleaseOrMintInV1 calldata releaseOrMintIn
) external virtual override returns (Pool.ReleaseOrMintOutV1 memory) {
_validateReleaseOrMint(releaseOrMintIn);

uint256 balancePre = IBurnMintERC20(address(i_token)).balanceOf(releaseOrMintIn.receiver);

// Mint to the receiver
IBurnMintERC20(address(i_token)).mint(releaseOrMintIn.receiver, releaseOrMintIn.amount);

uint256 balancePost = IBurnMintERC20(address(i_token)).balanceOf(releaseOrMintIn.receiver);

// Mint should not reduce the number of tokens in the receiver, if it does it will revert the call.
if (balancePost < balancePre) {
revert NegativeMintAmount(balancePre - balancePost);
}

emit Minted(msg.sender, releaseOrMintIn.receiver, balancePost - balancePre);

return Pool.ReleaseOrMintOutV1({destinationAmount: balancePost - balancePre});
}
}
6 changes: 4 additions & 2 deletions contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/tok
contract BurnWithFromMintTokenPool is BurnMintTokenPoolAbstract, ITypeAndVersion {
using SafeERC20 for IBurnMintERC20;

string public constant override typeAndVersion = "BurnWithFromMintTokenPool 1.5.0";

constructor(
IBurnMintERC20 token,
address[] memory allowlist,
Expand All @@ -35,4 +33,8 @@ contract BurnWithFromMintTokenPool is BurnMintTokenPoolAbstract, ITypeAndVersion
function _burn(uint256 amount) internal virtual override {
IBurnMintERC20(address(i_token)).burn(address(this), amount);
}

function typeAndVersion() external pure virtual override returns (string memory) {
return "BurnWithFromMintTokenPool 1.5.0";
}
}
27 changes: 27 additions & 0 deletions contracts/src/v0.8/ccip/test/helpers/ERC20RebasingHelper.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.24;

import {ERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/ERC20.sol";

contract ERC20RebasingHelper is ERC20 {
uint16 public s_multiplierPercentage = 100;
bool public s_mintShouldBurn = false;

constructor() ERC20("Rebasing", "REB") {}

function mint(address to, uint256 amount) external {
if (!s_mintShouldBurn) {
_mint(to, amount * s_multiplierPercentage / 100);
return;
}
_burn(to, amount * s_multiplierPercentage / 100);
}

function setMultiplierPercentage(uint16 multiplierPercentage) external {
s_multiplierPercentage = multiplierPercentage;
}

function setMintShouldBurn(bool mintShouldBurn) external {
s_mintShouldBurn = mintShouldBurn;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.24;

import {IBurnMintERC20} from "../../../shared/token/ERC20/IBurnMintERC20.sol";

import {Pool} from "../../libraries/Pool.sol";
import {BurnWithFromMintRebasingTokenPool} from "../../pools/BurnWithFromMintRebasingTokenPool.sol";
import {BurnMintSetup} from "./BurnMintSetup.t.sol";

import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol";
import {ERC20RebasingHelper} from "../helpers/ERC20RebasingHelper.sol";

contract BurnWithFromMintRebasingTokenPoolSetup is BurnMintSetup {
BurnWithFromMintRebasingTokenPool internal s_pool;
ERC20RebasingHelper internal s_rebasingToken;

function setUp() public virtual override {
BurnMintSetup.setUp();

s_rebasingToken = new ERC20RebasingHelper();

s_pool = new BurnWithFromMintRebasingTokenPool(
IBurnMintERC20(address(s_rebasingToken)), new address[](0), address(s_mockRMN), address(s_sourceRouter)
);

_applyChainUpdates(address(s_pool));

deal(address(s_rebasingToken), OWNER, 1e18);

vm.startPrank(s_burnMintOffRamp);
}
}

contract BurnWithFromMintTokenPool_releaseOrMint is BurnWithFromMintRebasingTokenPoolSetup {
function test_Setup_Success() public view {
assertEq(address(s_rebasingToken), address(s_pool.getToken()));
assertEq(address(s_mockRMN), s_pool.getRmnProxy());
assertEq(false, s_pool.getAllowListEnabled());
assertEq(type(uint256).max, s_rebasingToken.allowance(address(s_pool), address(s_pool)));
assertEq("BurnWithFromMintRebasingTokenPool 1.5.0", s_pool.typeAndVersion());
}

function test_releaseOrMint_Success() public {
uint256 amount = 1000;
uint256 balancePre = s_rebasingToken.balanceOf(address(OWNER));

Pool.ReleaseOrMintOutV1 memory releaseOrMintOut = s_pool.releaseOrMint(_getReleaseOrMintIn(amount));

assertEq(amount, releaseOrMintOut.destinationAmount);
assertEq(balancePre + amount, s_rebasingToken.balanceOf(address(OWNER)));
}

function testFuzz_releaseOrMint_rebasing_success(uint16 multiplierPercentage) public {
uint256 amount = 1000;
uint256 expectedAmount = amount * multiplierPercentage / 100;
s_rebasingToken.setMultiplierPercentage(multiplierPercentage);

uint256 balancePre = s_rebasingToken.balanceOf(address(OWNER));

Pool.ReleaseOrMintOutV1 memory releaseOrMintOut = s_pool.releaseOrMint(_getReleaseOrMintIn(amount));

assertEq(expectedAmount, releaseOrMintOut.destinationAmount);
assertEq(balancePre + expectedAmount, s_rebasingToken.balanceOf(address(OWNER)));
}

function test_releaseOrMint_NegativeMintAmount_reverts() public {
uint256 amount = 1000;
s_rebasingToken.setMintShouldBurn(true);

vm.expectRevert(abi.encodeWithSelector(BurnWithFromMintRebasingTokenPool.NegativeMintAmount.selector, amount));

s_pool.releaseOrMint(_getReleaseOrMintIn(amount));
}

function _getReleaseOrMintIn(uint256 amount) internal view returns (Pool.ReleaseOrMintInV1 memory) {
return Pool.ReleaseOrMintInV1({
originalSender: bytes(""),
receiver: OWNER,
amount: amount,
localToken: address(s_rebasingToken),
remoteChainSelector: DEST_CHAIN_SELECTOR,
sourcePoolAddress: abi.encode(s_remoteBurnMintPool),
sourcePoolData: "",
offchainTokenData: ""
});
}
}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ GETH_VERSION: 1.13.8
burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 1e60c28ad796a220a38043b369dec8d9bffe23e1c7d9895760e30672872afd06
burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 3e8e3358f0bb520af069a7d37ea625940a88461a54418b1d5925eabced8c74df
burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 717c079d5d13300cf3c3ee871c6e5bf9af904411f204fb081a9f3b263cca1391
burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 6333d0314d0bd29e75ea5e05fe62a4516ade0c6db91c30b6f93645035db52ed8
burn_with_from_mint_rebasing_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintRebasingTokenPool/BurnWithFromMintRebasingTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintRebasingTokenPool/BurnWithFromMintRebasingTokenPool.bin ec9b95105a33de14b078c1261d9cd9d6f3011e940a819b52f11a963951d4bb89
burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 734c2a0ea8f1224b5f01ed849410209e74b4e3427e8bfddb8ff5dd8ead5f2d8d
burn_with_from_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.bin 1ed5c299f928529081dc01b7a46db2b5e6728001767863495a7675d8db99a9e2
ccip_encoding_utils: ../../../contracts/solc/v0.8.24/ICCIPEncodingUtils/ICCIPEncodingUtils.abi ../../../contracts/solc/v0.8.24/ICCIPEncodingUtils/ICCIPEncodingUtils.bin 2e6fa009821d30a24efdc9f9d14b2269fb9a51cb7d536ea8b2d29d97dd8b591c
ccip_home: ../../../contracts/solc/v0.8.24/CCIPHome/CCIPHome.abi ../../../contracts/solc/v0.8.24/CCIPHome/CCIPHome.bin c570b86f8ae7697d3478e70625e06f0f682e75c1f0b7538f4b6f581b0d294b2b
Expand Down
1 change: 1 addition & 0 deletions core/gethwrappers/ccip/go_generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ package ccip
//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin LockReleaseTokenPoolAndProxy lock_release_token_pool_and_proxy
//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin TokenPool token_pool
//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin USDCTokenPool usdc_token_pool
//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/BurnWithFromMintRebasingTokenPool/BurnWithFromMintRebasingTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintRebasingTokenPool/BurnWithFromMintRebasingTokenPool.bin BurnWithFromMintRebasingTokenPool burn_with_from_mint_rebasing_token_pool

// Helpers
//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.abi ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.bin MockV3Aggregator mock_v3_aggregator_contract
Expand Down

0 comments on commit 1f26f49

Please sign in to comment.