diff --git a/contracts/src/v0.8/ccip/pools/GHO/diffs/BurnMintTokenPoolAbstract_diff.md b/contracts/src/v0.8/ccip/pools/GHO/diffs/BurnMintTokenPoolAbstract_diff.md index 11c20c0a6d..2255b2ca44 100644 --- a/contracts/src/v0.8/ccip/pools/GHO/diffs/BurnMintTokenPoolAbstract_diff.md +++ b/contracts/src/v0.8/ccip/pools/GHO/diffs/BurnMintTokenPoolAbstract_diff.md @@ -1,18 +1,19 @@ ```diff -diff --git a/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol b/src/v0.8/ccip/pools/UpgradeableBurnMintTokenPoolAbstract.sol -index f5eb135186..651965e40b 100644 +diff --git a/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol b/src/v0.8/ccip/pools/GHO/UpgradeableBurnMintTokenPoolAbstract.sol +index f5eb135186..e228732855 100644 --- a/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol -+++ b/src/v0.8/ccip/pools/UpgradeableBurnMintTokenPoolAbstract.sol ++++ b/src/v0.8/ccip/pools/GHO/UpgradeableBurnMintTokenPoolAbstract.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.19; +pragma solidity ^0.8.0; - - import {IBurnMintERC20} from "../../shared/token/ERC20/IBurnMintERC20.sol"; - + +-import {IBurnMintERC20} from "../../shared/token/ERC20/IBurnMintERC20.sol"; ++import {IBurnMintERC20} from "../../../shared/token/ERC20/IBurnMintERC20.sol"; + -import {TokenPool} from "./TokenPool.sol"; +import {UpgradeableTokenPool} from "./UpgradeableTokenPool.sol"; - + -abstract contract BurnMintTokenPoolAbstract is TokenPool { +abstract contract UpgradeableBurnMintTokenPoolAbstract is UpgradeableTokenPool { /// @notice Contains the specific burn call for a pool. diff --git a/contracts/src/v0.8/ccip/pools/GHO/diffs/BurnMintTokenPool_diff.md b/contracts/src/v0.8/ccip/pools/GHO/diffs/BurnMintTokenPool_diff.md index 1dfabb1e60..67b07df888 100644 --- a/contracts/src/v0.8/ccip/pools/GHO/diffs/BurnMintTokenPool_diff.md +++ b/contracts/src/v0.8/ccip/pools/GHO/diffs/BurnMintTokenPool_diff.md @@ -1,39 +1,42 @@ ```diff -diff --git a/src/v0.8/ccip/pools/BurnMintTokenPool.sol b/src/v0.8/ccip/pools/UpgradeableBurnMintTokenPool.sol -index 9af0f22f4c..f07f8c3a28 100644 +diff --git a/src/v0.8/ccip/pools/BurnMintTokenPool.sol b/src/v0.8/ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol +index 9af0f22f4c..63044b4d7e 100644 --- a/src/v0.8/ccip/pools/BurnMintTokenPool.sol -+++ b/src/v0.8/ccip/pools/UpgradeableBurnMintTokenPool.sol -@@ -1,29 +1,66 @@ ++++ b/src/v0.8/ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol +@@ -1,29 +1,62 @@ // SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.19; +pragma solidity ^0.8.0; - - import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; - import {IBurnMintERC20} from "../../shared/token/ERC20/IBurnMintERC20.sol"; - + +-import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; +-import {IBurnMintERC20} from "../../shared/token/ERC20/IBurnMintERC20.sol"; ++import {Initializable} from "solidity-utils/contracts/transparent-proxy/Initializable.sol"; + -import {TokenPool} from "./TokenPool.sol"; -import {BurnMintTokenPoolAbstract} from "./BurnMintTokenPoolAbstract.sol"; -+import {UpgradeableTokenPool} from "./UpgradeableTokenPool.sol"; -+import {UpgradeableBurnMintTokenPoolAbstract} from "./UpgradeableBurnMintTokenPoolAbstract.sol"; - ++import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; ++import {IBurnMintERC20} from "../../../shared/token/ERC20/IBurnMintERC20.sol"; + -/// @notice This pool mints and burns a 3rd-party token. -/// @dev Pool whitelisting mode is set in the constructor and cannot be modified later. -/// It either accepts any address as originalSender, or only accepts whitelisted originalSender. -/// The only way to change whitelisting mode is to deploy a new pool. -/// If that is expected, please make sure the token's burner/minter roles are adjustable. -contract BurnMintTokenPool is BurnMintTokenPoolAbstract, ITypeAndVersion { -+import {IRouter} from "../interfaces/IRouter.sol"; -+import {VersionedInitializable} from "./VersionedInitializable.sol"; ++import {UpgradeableTokenPool} from "./UpgradeableTokenPool.sol"; ++import {UpgradeableBurnMintTokenPoolAbstract} from "./UpgradeableBurnMintTokenPoolAbstract.sol"; ++ ++import {IRouter} from "../../interfaces/IRouter.sol"; + +/// @title UpgradeableBurnMintTokenPool +/// @author Aave Labs +/// @notice Upgradeable version of Chainlink's CCIP BurnMintTokenPool +/// @dev Contract adaptations: -+/// - Implementation of VersionedInitializable to allow upgrades ++/// - Implementation of Initializable to allow upgrades +/// - Move of allowlist and router definition to initialization stage -+contract UpgradeableBurnMintTokenPool is VersionedInitializable, UpgradeableBurnMintTokenPoolAbstract, ITypeAndVersion { ++contract UpgradeableBurnMintTokenPool is Initializable, UpgradeableBurnMintTokenPoolAbstract, ITypeAndVersion { string public constant override typeAndVersion = "BurnMintTokenPool 1.4.0"; - + + /// @dev Constructor + /// @param token The bridgeable token that is managed by this pool. + /// @param armProxy The address of the arm proxy @@ -47,7 +50,7 @@ index 9af0f22f4c..f07f8c3a28 100644 - ) TokenPool(token, allowlist, armProxy, router) {} + bool allowlistEnabled + ) UpgradeableTokenPool(IBurnMintERC20(token), armProxy, allowlistEnabled) {} - + - /// @inheritdoc BurnMintTokenPoolAbstract + /// @dev Initializer + /// @dev The address passed as `owner` must accept ownership after initialization. @@ -77,11 +80,6 @@ index 9af0f22f4c..f07f8c3a28 100644 + /// @return The revision number + function REVISION() public pure virtual returns (uint256) { + return 1; -+ } -+ -+ /// @inheritdoc VersionedInitializable -+ function getRevision() internal pure virtual override returns (uint256) { -+ return REVISION(); + } } ``` diff --git a/contracts/src/v0.8/ccip/pools/GHO/diffs/LockReleaseTokenPool_diff.md b/contracts/src/v0.8/ccip/pools/GHO/diffs/LockReleaseTokenPool_diff.md index ac5d7bf30e..a97f8c0f4b 100644 --- a/contracts/src/v0.8/ccip/pools/GHO/diffs/LockReleaseTokenPool_diff.md +++ b/contracts/src/v0.8/ccip/pools/GHO/diffs/LockReleaseTokenPool_diff.md @@ -1,61 +1,62 @@ ```diff -diff --git a/src/v0.8/ccip/pools/LockReleaseTokenPool.sol b/src/v0.8/ccip/pools/UpgradeableLockReleaseTokenPool.sol -index 1a17fa0398..7ca3d5f389 100644 +diff --git a/src/v0.8/ccip/pools/LockReleaseTokenPool.sol b/src/v0.8/ccip/pools/GHO/UpgradeableLockReleaseTokenPool.sol +index 1a17fa0398..d7d3c64e74 100644 --- a/src/v0.8/ccip/pools/LockReleaseTokenPool.sol -+++ b/src/v0.8/ccip/pools/UpgradeableLockReleaseTokenPool.sol -@@ -1,26 +1,41 @@ ++++ b/src/v0.8/ccip/pools/GHO/UpgradeableLockReleaseTokenPool.sol +@@ -1,26 +1,37 @@ // SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.19; +pragma solidity ^0.8.0; - - import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; - import {ILiquidityContainer} from "../../rebalancer/interfaces/ILiquidityContainer.sol"; - + +-import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; +-import {ILiquidityContainer} from "../../rebalancer/interfaces/ILiquidityContainer.sol"; ++import {Initializable} from "solidity-utils/contracts/transparent-proxy/Initializable.sol"; + -import {TokenPool} from "./TokenPool.sol"; +-import {RateLimiter} from "../libraries/RateLimiter.sol"; ++import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; ++import {ILiquidityContainer} from "../../../rebalancer/interfaces/ILiquidityContainer.sol"; + +-import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +-import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; +import {UpgradeableTokenPool} from "./UpgradeableTokenPool.sol"; - import {RateLimiter} from "../libraries/RateLimiter.sol"; - - import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; - import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; - ++import {RateLimiter} from "../../libraries/RateLimiter.sol"; + -/// @notice Token pool used for tokens on their native chain. This uses a lock and release mechanism. -/// Because of lock/unlock requiring liquidity, this pool contract also has function to add and remove -/// liquidity. This allows for proper bookkeeping for both user and liquidity provider balances. -/// @dev One token per LockReleaseTokenPool. -contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion { -+import {IRouter} from "../interfaces/IRouter.sol"; -+import {VersionedInitializable} from "./VersionedInitializable.sol"; ++import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; ++import {SafeERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; ++ ++import {IRouter} from "../../interfaces/IRouter.sol"; + +/// @title UpgradeableLockReleaseTokenPool +/// @author Aave Labs +/// @notice Upgradeable version of Chainlink's CCIP LockReleaseTokenPool +/// @dev Contract adaptations: -+/// - Implementation of VersionedInitializable to allow upgrades ++/// - Implementation of Initializable to allow upgrades +/// - Move of allowlist and router definition to initialization stage +/// - Addition of a bridge limit to regulate the maximum amount of tokens that can be transferred out (burned/locked) -+contract UpgradeableLockReleaseTokenPool is -+ VersionedInitializable, -+ UpgradeableTokenPool, -+ ILiquidityContainer, -+ ITypeAndVersion -+{ ++contract UpgradeableLockReleaseTokenPool is Initializable, UpgradeableTokenPool, ILiquidityContainer, ITypeAndVersion { using SafeERC20 for IERC20; - + error InsufficientLiquidity(); error LiquidityNotAccepted(); error Unauthorized(address caller); - + + error BridgeLimitExceeded(uint256 bridgeLimit); + error NotEnoughBridgedAmount(); + event BridgeLimitUpdated(uint256 oldBridgeLimit, uint256 newBridgeLimit); + string public constant override typeAndVersion = "LockReleaseTokenPool 1.4.0"; - + /// @dev The unique lock release pool flag to signal through EIP 165. -@@ -37,16 +52,55 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion +@@ -37,16 +48,55 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion /// @dev Can be address(0) if none is configured. address internal s_rateLimitAdmin; - + + /// @notice Maximum amount of tokens that can be bridged to other chains + uint256 private s_bridgeLimit; + /// @notice Amount of tokens bridged (transferred out) @@ -83,7 +84,7 @@ index 1a17fa0398..7ca3d5f389 100644 + ) UpgradeableTokenPool(IERC20(token), armProxy, allowlistEnabled) { i_acceptLiquidity = acceptLiquidity; } - + + /// @dev Initializer + /// @dev The address passed as `owner` must accept ownership after initialization. + /// @dev The `allowlist` is only effective if pool is set to access-controlled mode @@ -113,7 +114,7 @@ index 1a17fa0398..7ca3d5f389 100644 /// @notice Locks the token in the pool /// @param amount Amount to lock /// @dev The whenHealthy check is important to ensure that even if a ramp is compromised -@@ -66,6 +120,9 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion +@@ -66,6 +116,9 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion whenHealthy returns (bytes memory) { @@ -123,7 +124,7 @@ index 1a17fa0398..7ca3d5f389 100644 _consumeOutboundRateLimit(remoteChainSelector, amount); emit Locked(msg.sender, amount); return ""; -@@ -83,6 +140,11 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion +@@ -83,6 +136,11 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion uint64 remoteChainSelector, bytes memory ) external virtual override onlyOffRamp(remoteChainSelector) whenHealthy { @@ -135,10 +136,10 @@ index 1a17fa0398..7ca3d5f389 100644 _consumeInboundRateLimit(remoteChainSelector, amount); getToken().safeTransfer(receiver, amount); emit Released(msg.sender, receiver, amount); -@@ -120,11 +182,46 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion +@@ -120,11 +178,46 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion s_rateLimitAdmin = rateLimitAdmin; } - + + /// @notice Sets the bridge limit, the maximum amount of tokens that can be bridged out + /// @dev Only callable by the owner or the bridge limit admin. + /// @dev Bridge limit changes should be carefully managed, specially when reducing below the current bridged amount @@ -173,7 +174,7 @@ index 1a17fa0398..7ca3d5f389 100644 function getRateLimitAdmin() external view returns (address) { return s_rateLimitAdmin; } - + + /// @notice Gets the bridge limiter admin address. + function getBridgeLimitAdmin() external view returns (address) { + return s_bridgeLimitAdmin; @@ -182,8 +183,8 @@ index 1a17fa0398..7ca3d5f389 100644 /// @notice Checks if the pool can accept liquidity. /// @return true if the pool can accept liquidity, false otherwise. function canAcceptLiquidity() external view returns (bool) { -@@ -166,4 +263,15 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion - +@@ -166,4 +259,10 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion + _setRateLimitConfig(remoteChainSelector, outboundConfig, inboundConfig); } + @@ -191,11 +192,6 @@ index 1a17fa0398..7ca3d5f389 100644 + /// @return The revision number + function REVISION() public pure virtual returns (uint256) { + return 1; -+ } -+ -+ /// @inheritdoc VersionedInitializable -+ function getRevision() internal pure virtual override returns (uint256) { -+ return REVISION(); + } } ``` diff --git a/contracts/src/v0.8/ccip/pools/GHO/diffs/TokenPool_diff.md b/contracts/src/v0.8/ccip/pools/GHO/diffs/TokenPool_diff.md index 6ff8893172..fcdc197580 100644 --- a/contracts/src/v0.8/ccip/pools/GHO/diffs/TokenPool_diff.md +++ b/contracts/src/v0.8/ccip/pools/GHO/diffs/TokenPool_diff.md @@ -1,16 +1,32 @@ ```diff -diff --git a/src/v0.8/ccip/pools/TokenPool.sol b/src/v0.8/ccip/pools/UpgradeableTokenPool.sol -index b3571bb449..fcd8948098 100644 +diff --git a/src/v0.8/ccip/pools/TokenPool.sol b/src/v0.8/ccip/pools/GHO/UpgradeableTokenPool.sol +index b3571bb449..ee359ac1f8 100644 --- a/src/v0.8/ccip/pools/TokenPool.sol -+++ b/src/v0.8/ccip/pools/UpgradeableTokenPool.sol -@@ -1,5 +1,5 @@ ++++ b/src/v0.8/ccip/pools/GHO/UpgradeableTokenPool.sol +@@ -1,21 +1,21 @@ // SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.19; +pragma solidity ^0.8.0; - - import {IPool} from "../interfaces/pools/IPool.sol"; - import {IARM} from "../interfaces/IARM.sol"; -@@ -15,7 +15,7 @@ import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts + +-import {IPool} from "../interfaces/pools/IPool.sol"; +-import {IARM} from "../interfaces/IARM.sol"; +-import {IRouter} from "../interfaces/IRouter.sol"; ++import {IPool} from "../../interfaces/pools/IPool.sol"; ++import {IARM} from "../../interfaces/IARM.sol"; ++import {IRouter} from "../../interfaces/IRouter.sol"; + +-import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol"; +-import {RateLimiter} from "../libraries/RateLimiter.sol"; ++import {OwnerIsCreator} from "../../../shared/access/OwnerIsCreator.sol"; ++import {RateLimiter} from "../../libraries/RateLimiter.sol"; + +-import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +-import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; +-import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; ++import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; ++import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; ++import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; + /// @notice Base abstract class with common functions for all token pools. /// A token pool serves as isolated place for holding tokens and token specific logic /// that may execute as tokens move across the bridge. @@ -30,7 +46,7 @@ index b3571bb449..fcd8948098 100644 /// degrees and prefer different limits) - mapping(uint64 remoteChainSelector => RateLimiter.TokenBucket) internal s_inboundRateLimits; + mapping(uint64 => RateLimiter.TokenBucket) internal s_inboundRateLimits; - + - constructor(IERC20 token, address[] memory allowlist, address armProxy, address router) { - if (address(token) == address(0) || router == address(0)) revert ZeroAddressNotAllowed(); + constructor(IERC20 token, address armProxy, bool allowlistEnabled) { @@ -46,6 +62,6 @@ index b3571bb449..fcd8948098 100644 - } + i_allowlistEnabled = allowlistEnabled; } - + /// @notice Get ARM proxy address ```