Skip to content

Commit

Permalink
feat: upgrade remote pool
Browse files Browse the repository at this point in the history
  • Loading branch information
CheyenneAtapour committed Jul 17, 2024
1 parent 790bcef commit 19829fd
Show file tree
Hide file tree
Showing 4 changed files with 228 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import {Initializable} from "solidity-utils/contracts/transparent-proxy/Initializable.sol";

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

import {UpgradeableTokenPool} from "./UpgradeableTokenPool.sol";
import {UpgradeableBurnMintTokenPoolAbstract} from "./UpgradeableBurnMintTokenPoolAbstract.sol";

import {IRouter} from "../../interfaces/IRouter.sol";

/// @title UpgradeableBurnMintTokenPoolOld
/// @author Aave Labs
/// @notice Upgradeable version of Chainlink's CCIP BurnMintTokenPool
/// @dev Contract adaptations:
/// - Implementation of Initializable to allow upgrades
/// - Move of allowlist and router definition to initialization stage
contract UpgradeableBurnMintTokenPoolOld 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
/// @param allowlistEnabled True if pool is set to access-controlled mode, false otherwise
constructor(
address token,
address armProxy,
bool allowlistEnabled
) UpgradeableTokenPool(IBurnMintERC20(token), armProxy, allowlistEnabled) {}

/// @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
/// @param owner The address of the owner
/// @param allowlist A set of addresses allowed to trigger lockOrBurn as original senders
/// @param router The address of the router
function initialize(address owner, address[] memory allowlist, address router) public virtual initializer {
if (owner == address(0)) revert ZeroAddressNotAllowed();
if (router == address(0)) revert ZeroAddressNotAllowed();
_transferOwnership(owner);

s_router = IRouter(router);

// Pool can be set as permissioned or permissionless at deployment time only to save hot-path gas.
if (i_allowlistEnabled) {
_applyAllowListUpdates(new address[](0), allowlist);
}
}

/// @inheritdoc UpgradeableBurnMintTokenPoolAbstract
function _burn(uint256 amount) internal virtual override {
IBurnMintERC20(address(i_token)).burn(amount);
}
}
45 changes: 45 additions & 0 deletions contracts/src/v0.8/ccip/test/pools/GHO/GhoBaseTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {IBurnMintERC20} from "../../../../shared/token/ERC20/IBurnMintERC20.sol"
import {IPool} from "../../../interfaces/pools/IPool.sol";
import {UpgradeableLockReleaseTokenPool} from "../../../pools/GHO/UpgradeableLockReleaseTokenPool.sol";
import {UpgradeableBurnMintTokenPool} from "../../../pools/GHO/UpgradeableBurnMintTokenPool.sol";
import {UpgradeableBurnMintTokenPoolOld} from "../../../pools/GHO/UpgradeableBurnMintTokenPoolOld.sol";
import {UpgradeableTokenPool} from "../../../pools/GHO/UpgradeableTokenPool.sol";
import {RateLimiter} from "../../../libraries/RateLimiter.sol";
import {BaseTest} from "../../BaseTest.t.sol";
Expand Down Expand Up @@ -65,6 +66,50 @@ abstract contract GhoBaseTest is BaseTest {
return address(tokenPoolProxy);
}

function _deployUpgradeableBurnMintTokenPoolOld(
address ghoToken,
address arm,
address router,
address owner,
address proxyAdmin
) internal returns (address) {
// Deploy BurnMintTokenPool for GHO token on source chain
UpgradeableBurnMintTokenPoolOld tokenPoolImpl = new UpgradeableBurnMintTokenPoolOld(ghoToken, arm, false);
// proxy deploy and init
address[] memory emptyArray = new address[](0);
bytes memory tokenPoolInitParams = abi.encodeWithSignature(
"initialize(address,address[],address)",
owner,
emptyArray,
router
);
TransparentUpgradeableProxy tokenPoolProxy = new TransparentUpgradeableProxy(
address(tokenPoolImpl),
proxyAdmin,
tokenPoolInitParams
);
// Manage ownership
vm.stopPrank();
vm.prank(owner);
UpgradeableBurnMintTokenPoolOld(address(tokenPoolProxy)).acceptOwnership();
vm.startPrank(OWNER);

return address(tokenPoolProxy);
}

function _upgradeUpgradeableBurnMintTokenPool(
address payable tokenPoolProxy,
address ghoToken,
address arm,
address proxyAdmin
) internal {
// Deploy BurnMintTokenPool for GHO token on source chain
UpgradeableBurnMintTokenPool tokenPoolImpl = new UpgradeableBurnMintTokenPool(ghoToken, arm, false);
// proxy upgrade
vm.startPrank(proxyAdmin);
TransparentUpgradeableProxy(tokenPoolProxy).upgradeTo(address(tokenPoolImpl));
}

function _deployUpgradeableLockReleaseTokenPool(
address ghoToken,
address arm,
Expand Down
49 changes: 49 additions & 0 deletions contracts/src/v0.8/ccip/test/pools/GHO/GhoTokenPoolRemoteOld.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.19;

import {GhoToken} from "@aave/gho-core/gho/GhoToken.sol";
import {TransparentUpgradeableProxy} from "solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol";

import {stdError} from "forge-std/Test.sol";
import {MockUpgradeable} from "../../mocks/MockUpgradeable.sol";
import {UpgradeableTokenPool} from "../../../pools/GHO/UpgradeableTokenPool.sol";
import {EVM2EVMOnRamp} from "../../../onRamp/EVM2EVMOnRamp.sol";
import {EVM2EVMOffRamp} from "../../../offRamp/EVM2EVMOffRamp.sol";
import {BurnMintTokenPool} from "../../../pools/BurnMintTokenPool.sol";
import {UpgradeableBurnMintTokenPool} from "../../../pools/GHO/UpgradeableBurnMintTokenPool.sol";
import {RateLimiter} from "../../../libraries/RateLimiter.sol";
import {GhoTokenPoolRemoteSetupOld} from "./GhoTokenPoolRemoteSetupOld.t.sol";

contract GhoTokenPoolRemoteOld_setRateLimitAdmin is GhoTokenPoolRemoteSetupOld {
/*function testSetRateLimitAdminSuccess() public {
assertEq(address(0), s_pool.getRateLimitAdmin());
changePrank(AAVE_DAO);
s_pool.setRateLimitAdmin(OWNER);
assertEq(OWNER, s_pool.getRateLimitAdmin());
}*/

// Reverts

// Should fail because old implementation does not have rate limiter
function testSetRateLimitRevert() public {
changePrank(AAVE_DAO);
vm.expectRevert();
s_pool.setRateLimitAdmin(OWNER);
}

function testSetRateLimitAfterUpgrade() public {
_upgradeUpgradeableBurnMintTokenPool(payable(address(s_pool)), address(s_burnMintERC677), ARM_PROXY, PROXY_ADMIN);
changePrank(AAVE_DAO);
s_pool.setRateLimitAdmin(OWNER);
assertEq(OWNER, s_pool.getRateLimitAdmin());
}

/*
function testSetRateLimitAdminReverts() public {
vm.startPrank(STRANGER);
vm.expectRevert("Only callable by owner");
s_pool.setRateLimitAdmin(STRANGER);
}
*/
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.19;

import {GhoToken} from "@aave/gho-core/gho/GhoToken.sol";
import {TransparentUpgradeableProxy} from "solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol";

import {stdError} from "forge-std/Test.sol";
import {UpgradeableTokenPool} from "../../../pools/GHO/UpgradeableTokenPool.sol";
import {Router} from "../../../Router.sol";
import {BurnMintERC677} from "../../../../shared/token/ERC677/BurnMintERC677.sol";
import {UpgradeableBurnMintTokenPoolOld} from "../../../pools/GHO/UpgradeableBurnMintTokenPoolOld.sol";
import {UpgradeableBurnMintTokenPool} from "../../../pools/GHO/UpgradeableBurnMintTokenPool.sol";
import {RouterSetup} from "../../router/RouterSetup.t.sol";
import {BaseTest} from "../../BaseTest.t.sol";
import {GhoBaseTest} from "./GhoBaseTest.t.sol";

contract GhoTokenPoolRemoteSetupOld is RouterSetup, GhoBaseTest {
event Transfer(address indexed from, address indexed to, uint256 value);
event TokensConsumed(uint256 tokens);
event Burned(address indexed sender, uint256 amount);

BurnMintERC677 internal s_burnMintERC677;
address internal s_burnMintOffRamp = makeAddr("burn_mint_offRamp");
address internal s_burnMintOnRamp = makeAddr("burn_mint_onRamp");

UpgradeableBurnMintTokenPool internal s_pool;

function setUp() public virtual override(RouterSetup, BaseTest) {
RouterSetup.setUp();

// GHO deployment
GhoToken ghoToken = new GhoToken(AAVE_DAO);
s_burnMintERC677 = BurnMintERC677(address(ghoToken));

s_pool = UpgradeableBurnMintTokenPool(
_deployUpgradeableBurnMintTokenPoolOld(
address(s_burnMintERC677),
address(s_mockARM),
address(s_sourceRouter),
AAVE_DAO,
PROXY_ADMIN
)
);

// Give mint and burn privileges to source UpgradeableTokenPool (GHO-specific related)
vm.stopPrank();
vm.startPrank(AAVE_DAO);
GhoToken(address(s_burnMintERC677)).grantRole(
GhoToken(address(s_burnMintERC677)).FACILITATOR_MANAGER_ROLE(),
AAVE_DAO
);
GhoToken(address(s_burnMintERC677)).addFacilitator(address(s_pool), "UpgradeableTokenPool", type(uint128).max);
vm.stopPrank();

_applyChainUpdates(address(s_pool));
}

function _applyChainUpdates(address pool) internal {
UpgradeableTokenPool.ChainUpdate[] memory chains = new UpgradeableTokenPool.ChainUpdate[](1);
chains[0] = UpgradeableTokenPool.ChainUpdate({
remoteChainSelector: DEST_CHAIN_SELECTOR,
allowed: true,
outboundRateLimiterConfig: getOutboundRateLimiterConfig(),
inboundRateLimiterConfig: getInboundRateLimiterConfig()
});

vm.startPrank(AAVE_DAO);
UpgradeableBurnMintTokenPool(pool).applyChainUpdates(chains);
vm.stopPrank();
vm.startPrank(OWNER);

Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1);
onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_burnMintOnRamp});
Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1);
offRampUpdates[0] = Router.OffRamp({sourceChainSelector: DEST_CHAIN_SELECTOR, offRamp: s_burnMintOffRamp});
s_sourceRouter.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates);
}
}

0 comments on commit 19829fd

Please sign in to comment.