Skip to content

Commit

Permalink
Refactor migrateLegacyToken function
Browse files Browse the repository at this point in the history
  • Loading branch information
ignasirv committed Sep 20, 2024
1 parent a73bba5 commit 7bc6cdb
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 65 deletions.
15 changes: 5 additions & 10 deletions contracts/v2/interfaces/IBridgeL2SovereignChains.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,14 @@ interface IBridgeL2SovereignChains is IPolygonZkEVMBridgeV2 {
error TokenNotMapped();

/**
* @dev Thrown when trying to migrate a token and both legacy and updated addresses are the same
* @dev Thrown when trying to migrate a legacy token that is already the current token
*/
error MigrationAddressesAreTheSame();
error TokenAlreadyUpdated();

/**
* @dev Thrown when trying to migrate a token and legacy and updated token info are different
* @dev Thrown when initializing sovereign bridge with invalid sovereign WETH token params
*/
error MigrationTokenInfoAreDifferent();

/**
* @dev Thrown when trying to migrate a token proposed updated token address is not the current mapped token address
*/
error InvalidUpdatedAddress();
error InvalidSovereignWETHAddressParams();

function initialize(
uint32 _networkID,
Expand All @@ -55,6 +50,6 @@ interface IBridgeL2SovereignChains is IPolygonZkEVMBridgeV2 {
bytes memory _gasTokenMetadata,
address _bridgeManager,
address sovereignWETHAddress,
bool __sovereignWETHAddressIsNotMintable
bool _sovereignWETHAddressIsNotMintable
) external;
}
111 changes: 56 additions & 55 deletions contracts/v2/sovereignChains/BridgeL2SovereignChain.sol
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ contract BridgeL2SovereignChain is
* @param _gasTokenMetadata Abi encoded gas token metadata
* @param _bridgeManager bridge manager address
* @param _sovereignWETHAddress sovereign WETH address
* @param __sovereignWETHAddressIsNotMintable Flag to indicate if the wrapped ETH is not mintable
* @param _sovereignWETHAddressIsNotMintable Flag to indicate if the wrapped ETH is not mintable
*/
function initialize(
uint32 _networkID,
Expand All @@ -100,7 +100,7 @@ contract BridgeL2SovereignChain is
bytes memory _gasTokenMetadata,
address _bridgeManager,
address _sovereignWETHAddress,
bool __sovereignWETHAddressIsNotMintable
bool _sovereignWETHAddressIsNotMintable
) public virtual initializer {
networkID = _networkID;
globalExitRootManager = _globalExitRootManager;
Expand All @@ -113,6 +113,13 @@ contract BridgeL2SovereignChain is
if (_gasTokenNetwork != 0) {
revert GasTokenNetworkMustBeZeroOnEther();
}
// Health check for sovereign WETH address
if (
_sovereignWETHAddress != address(0) ||
_sovereignWETHAddressIsNotMintable == true
) {
revert InvalidSovereignWETHAddressParams();
}
// WETHToken, gasTokenAddress and gasTokenNetwork will be 0
// gasTokenMetadata will be empty
} else {
Expand All @@ -131,7 +138,7 @@ contract BridgeL2SovereignChain is
WETHToken = TokenWrapped(_sovereignWETHAddress);
wrappedAddressIsNotMintable[
_sovereignWETHAddress
] = __sovereignWETHAddressIsNotMintable;
] = _sovereignWETHAddressIsNotMintable;
}
}

Expand Down Expand Up @@ -168,7 +175,7 @@ contract BridgeL2SovereignChain is
) external onlyBridgeManager {
// Make multiple calls to setSovereignTokenAddress
for (uint256 i = 0; i < sovereignTokenAddresses.length; i++) {
setSovereignTokenAddress(
_setSovereignTokenAddress(
sovereignTokenAddresses[i].originNetwork,
sovereignTokenAddresses[i].originTokenAddress,
sovereignTokenAddresses[i].sovereignTokenAddress,
Expand All @@ -194,7 +201,24 @@ contract BridgeL2SovereignChain is
address originTokenAddress,
address sovereignTokenAddress,
bool isNotMintable
) public onlyBridgeManager {
) external onlyBridgeManager {
_setSovereignTokenAddress(
originNetwork,
originTokenAddress,
sovereignTokenAddress,
isNotMintable
);
}

/**
* @notice Function to remap sovereign address
*/
function _setSovereignTokenAddress(
uint32 originNetwork,
address originTokenAddress,
address sovereignTokenAddress,
bool isNotMintable
) internal {
// origin and sovereign token address are not 0
if (
originTokenAddress == address(0) ||
Expand Down Expand Up @@ -272,76 +296,53 @@ contract BridgeL2SovereignChain is
/**
* @notice Moves old native or remapped token (legacy) to the new mapped token. If the token is mintable, it will be burnt and minted, otherwise it will be transferred
* @param legacyTokenAddress Address of legacy token to migrate
* @param updatedTokenAddress Address of updated token
* @param amount Legacy token balance to migrate
*/
function migrateLegacyToken(
address legacyTokenAddress,
address updatedTokenAddress
uint256 amount
) external {
// Origin and destination token addresses must be different
if(legacyTokenAddress == updatedTokenAddress) {
revert MigrationAddressesAreTheSame();
}
// Get current wrapped token address
TokenInformation memory legacyTokenInfo = wrappedTokenToTokenInfo[legacyTokenAddress];
TokenInformation memory updatedTokenInfo = wrappedTokenToTokenInfo[updatedTokenAddress];

// Check token info is the same for both tokens
if(legacyTokenInfo.originNetwork != updatedTokenInfo.originNetwork || legacyTokenInfo.originTokenAddress != updatedTokenInfo.originTokenAddress) {
revert MigrationTokenInfoAreDifferent();
}

// Check token address is not zero
if(legacyTokenAddress == address(0)) {
revert InvalidZeroAddress();
TokenInformation memory legacyTokenInfo = wrappedTokenToTokenInfo[
legacyTokenAddress
];
if (legacyTokenInfo.originTokenAddress == address(0)) {
revert TokenNotMapped();
}

// Check current token mapped is proposed updatedTokenAddress
address currentMappedAddress = tokenInfoToWrappedToken[keccak256(abi.encodePacked(legacyTokenInfo.originNetwork, legacyTokenInfo.originTokenAddress))];
address currentTokenAddress = tokenInfoToWrappedToken[
keccak256(
abi.encodePacked(
legacyTokenInfo.originNetwork,
legacyTokenInfo.originTokenAddress
)
)
];

if(currentMappedAddress != updatedTokenAddress) {
revert InvalidUpdatedAddress();
if (currentTokenAddress == legacyTokenAddress) {
revert TokenAlreadyUpdated();
}

// Proceed to migrate the token
uint256 legacyTokenBalance = IERC20Upgradeable(legacyTokenAddress)
.balanceOf(msg.sender);
if (wrappedAddressIsNotMintable[updatedTokenAddress]) {
// Transfer legacy tokens from user to bridge
IERC20Upgradeable(legacyTokenAddress).safeTransferFrom(
msg.sender,
address(this),
legacyTokenBalance
);
// Transfer migrated tokens from bridge to user
IERC20Upgradeable(updatedTokenAddress).safeTransfer(
msg.sender,
legacyTokenBalance
);
} else {
// Burn old tokens
TokenWrapped(legacyTokenAddress).burn(
msg.sender,
legacyTokenBalance
);
// Mint new tokens
TokenWrapped(updatedTokenAddress).mint(
msg.sender,
legacyTokenBalance
);
}
_bridgeWrappedAsset(TokenWrapped(legacyTokenAddress), amount);
_claimWrappedAsset(
TokenWrapped(currentTokenAddress),
msg.sender,
amount
);

// Trigger event
emit MigrateLegacyToken(
msg.sender,
legacyTokenAddress,
updatedTokenAddress,
legacyTokenBalance
currentTokenAddress,
amount
);
}

/**
* @notice Burn tokens from wrapped token to execute the bridge
* @notice Burn tokens from wrapped token to execute the bridge, if the token is not mintable it will be transferred
* note This function has been extracted to be able to override it by other contracts like Bridge2SovereignChain
* @param tokenWrapped Wrapped token to burnt
* @param amount Amount of tokens
Expand All @@ -366,7 +367,7 @@ contract BridgeL2SovereignChain is
}

/**
* @notice Mints tokens from wrapped token to proceed with the claim
* @notice Mints tokens from wrapped token to proceed with the claim, if the token is not mintable it will be transferred
* note This function has been extracted to be able to override it by other contracts like Bridge2SovereignChain
* @param tokenWrapped Wrapped token to mint
* @param destinationAddress Minted token receiver
Expand Down

0 comments on commit 7bc6cdb

Please sign in to comment.