From f70c750be2a116a5030da7c787ff2a83a36f2596 Mon Sep 17 00:00:00 2001 From: Leon Prouger Date: Thu, 1 Apr 2021 20:16:23 +0300 Subject: [PATCH 1/2] Change upgrateToken functionality --- .../PrimaryHomeMultiAMBErc20ToErc677.sol | 27 ++-- .../multibridge/primary_home_mediator.test.js | 147 ++++++++++-------- 2 files changed, 100 insertions(+), 74 deletions(-) diff --git a/contracts/upgradeable_contracts/multi_amb_erc20_to_erc677/multibridge/PrimaryHomeMultiAMBErc20ToErc677.sol b/contracts/upgradeable_contracts/multi_amb_erc20_to_erc677/multibridge/PrimaryHomeMultiAMBErc20ToErc677.sol index b565d3704..d60bd2fb2 100644 --- a/contracts/upgradeable_contracts/multi_amb_erc20_to_erc677/multibridge/PrimaryHomeMultiAMBErc20ToErc677.sol +++ b/contracts/upgradeable_contracts/multi_amb_erc20_to_erc677/multibridge/PrimaryHomeMultiAMBErc20ToErc677.sol @@ -81,26 +81,29 @@ contract PrimaryHomeMultiAMBErc20ToErc677 is HomeMultiAMBErc20ToErc677 { IBridgeRegistry(_token).removeBridge(_bridge); } - function upgradeToken(address _deprecatedToken, IBridgedTokensMigrator migratorContract) external onlyOwner { + /** + * @dev Upgrading home token to a new one. the old one will become deprecated and not available for relaying. + * He should be migrated to the upgraded token via the migration contract + * @param _deprecatedToken address of the current home token, will be deprecated after the call is done + * @param _upgradedToken address of the new upgraded token + */ + function upgradeToken(address _deprecatedToken, address _upgradedToken) external onlyOwner { require(isTokenRegistered(_deprecatedToken)); + DetailedERC20 token = DetailedERC20(_deprecatedToken); + uint8 decimals = token.decimals(); address foreignToken = foreignTokenAddress(_deprecatedToken); + _setTokenAddressPair(foreignToken, _upgradedToken); + _initializeTokenBridgeLimits(_upgradedToken, decimals); + _setFee(HOME_TO_FOREIGN_FEE, _upgradedToken, getFee(HOME_TO_FOREIGN_FEE, address(0))); + _setFee(FOREIGN_TO_HOME_FEE, _upgradedToken, getFee(FOREIGN_TO_HOME_FEE, address(0))); + // disable relaying the token to foregin network _setMaxPerTx(_deprecatedToken, uint256(0)); // unregistering the deprecated token _setMinPerTx(_deprecatedToken, uint256(0)); - - DetailedERC20 token = DetailedERC20(_deprecatedToken); - string memory name = token.name(); - string memory symbol = token.symbol(); - uint8 decimals = token.decimals(); - address upgradedToken = initializeTokenPair(foreignToken, name, symbol, decimals); - // Adding migrator contract as a bridge, so it will be able to mint tokens - IBridgeRegistry(upgradedToken).addBridge(migratorContract); - migratorContract.upgradeToken(_deprecatedToken, upgradedToken); - emit TokenDeprecated(_deprecatedToken); - emit NewTokenRegistered(foreignToken, upgradedToken); + emit NewTokenRegistered(foreignToken, _upgradedToken); } } diff --git a/test/multi_amb_erc20_to_erc677/multibridge/primary_home_mediator.test.js b/test/multi_amb_erc20_to_erc677/multibridge/primary_home_mediator.test.js index 50bdf1a14..7510db9b8 100644 --- a/test/multi_amb_erc20_to_erc677/multibridge/primary_home_mediator.test.js +++ b/test/multi_amb_erc20_to_erc677/multibridge/primary_home_mediator.test.js @@ -26,7 +26,7 @@ const otherMessageId = '0x35d3818e50234655f6aebb2a1cfbf30f59568d8a4ec72066fac5a2 const deployMessageId = '0x87b0c56ed7052872cd6ac5ad2e4d23b3e9bc7637837d099f083dae24aae5b2f2' const failedMessageId = '0x2ebc2ccc755acc8eaf9252e19573af708d644ab63a39619adb080a3500a4ff2e' -contract('PrimaryHomeMultiAMBErc20ToErc677', async accounts => { +contract.only('PrimaryHomeMultiAMBErc20ToErc677', async accounts => { let contract let token let ambBridgeContract @@ -1039,64 +1039,74 @@ contract('PrimaryHomeMultiAMBErc20ToErc677', async accounts => { }) describe('upgradeToken', () => { - let tokensMigrator + let tokensMigrator, upgradedToken beforeEach(async () => { homeToken = await bridgeToken(token) + upgradedToken = await PermittableToken.new('TEST on Fuse', 'TST', 18, 1337) tokensMigrator = await BridgedTokensMigrator.new() await tokensMigrator.initialize(contract.address).should.be.fulfilled expect(await contract.isTokenRegistered(homeToken.address)).to.be.equal(true) }) it('upgrading token from not an owner should be rejected', async () => { - await contract.upgradeToken(homeToken.address, tokensMigrator.address, { from: user }).should.be.rejected + await contract.upgradeToken(homeToken.address, upgradedToken.address, { from: user }).should.be.rejected }) it('upgrading not registered token should be rejected', async () => { - await contract.upgradeToken(token.address, tokensMigrator.address, { from: owner }).should.be.rejected + await contract.upgradeToken(token.address, upgradedToken.address, { from: owner }).should.be.rejected }) it('upgrading token from owner should pass', async () => { expect(await contract.withinLimit(homeToken.address, oneEther)).to.be.equal(true) - const { logs } = await contract.upgradeToken(homeToken.address, tokensMigrator.address, { from: owner }).should.be.fulfilled - expect(await contract.minPerTx(homeToken.address)).to.be.bignumber.equal(ZERO) - expect(await contract.maxPerTx(homeToken.address)).to.be.bignumber.equal(ZERO) - expect(await contract.withinLimit(homeToken.address, oneEther)).to.be.equal(false) + await contract.upgradeToken(homeToken.address, upgradedToken.address, { from: owner }).should.be.fulfilled expect(await contract.isTokenRegistered(homeToken.address)).to.be.equal(false) - expectEventInLogs(logs, 'TokenDeprecated') - expectEventInLogs(logs, 'NewTokenRegistered') + expect(await contract.isTokenRegistered(upgradedToken.address)).to.be.equal(true) }) it('cannot upgrade already upgraded token', async () => { - const { logs } = await contract.upgradeToken(homeToken.address, tokensMigrator.address, { from: owner }).should.be.fulfilled + await contract.upgradeToken(homeToken.address, upgradedToken.address, { from: owner }).should.be.fulfilled expect(await contract.minPerTx(homeToken.address)).to.be.bignumber.equal(ZERO) expect(await contract.isTokenRegistered(homeToken.address)).to.be.equal(false) - await contract.upgradeToken(homeToken.address, tokensMigrator.address, { from: owner }).should.be.rejected - await contract.upgradeToken(token.address, tokensMigrator.address, { from: owner }).should.be.rejected + await contract.upgradeToken(homeToken.address, upgradedToken.address, { from: owner }).should.be.rejected + await contract.upgradeToken(token.address, upgradedToken.address, { from: owner }).should.be.rejected }) describe('after upgradeToken', () => { - let upgradedToken + let logs beforeEach(async () => { - await contract.upgradeToken(homeToken.address, tokensMigrator.address, { from: owner }).should.be.fulfilled - + let response = await contract.upgradeToken(homeToken.address, upgradedToken.address, { from: owner }).should.be.fulfilled + logs = response.logs + }) + + it('upgrading token halts relaying of the deprecated token', async () => { + expect(await contract.minPerTx(homeToken.address)).to.be.bignumber.equal(ZERO) + expect(await contract.maxPerTx(homeToken.address)).to.be.bignumber.equal(ZERO) + expect(await contract.withinLimit(homeToken.address, oneEther)).to.be.equal(false) + expect(await contract.isTokenRegistered(homeToken.address)).to.be.equal(false) + expect(await contract.isTokenRegistered(upgradedToken.address)).to.be.equal(true) + + // expect(await contract.homeTokenAddress(token.address)).to.be.equal(homeToken.address) +// + }) + + it('upgrading token emits the correct events', async () => { + expectEventInLogs(logs, 'TokenDeprecated') + expectEventInLogs(logs, 'NewTokenRegistered') + const fromBlock = (await web3.eth.getBlock("latest")).number - const events = await getEvents(contract, { event: 'NewTokenRegistered' }, fromBlock) + let events = await getEvents(contract, { event: 'NewTokenRegistered' }, fromBlock) expect(events.length).to.be.equal(1) expect(events[0].returnValues.foreignToken).to.be.equal(token.address) - upgradedToken = await PermittableToken.at(events[0].returnValues.homeToken) - }) + expect(events[0].returnValues.homeToken).to.be.equal(upgradedToken.address) - it('upgrading token creates token similar to the original', async () => { - expect(await upgradedToken.isBridge(tokensMigrator.address)).to.be.equal(true) - - expect(await upgradedToken.name()).to.be.equal(await homeToken.name()) - expect(await upgradedToken.symbol()).to.be.equal(await homeToken.symbol()) - expect(await upgradedToken.decimals()).to.be.bignumber.equal(await homeToken.decimals()) + events = await getEvents(contract, { event: 'TokenDeprecated' }, fromBlock) + expect(events.length).to.be.equal(1) + expect(events[0].returnValues.token).to.be.equal(homeToken.address) }) it('upgrading token defines default limits', async () => { - expect(await upgradedToken.isBridge(tokensMigrator.address)).to.be.equal(true) + // expect(await upgradedToken.isBridge(tokensMigrator.address)).to.be.equal(true) expect(await contract.dailyLimit(upgradedToken.address)).to.be.bignumber.equal(dailyLimit) expect(await contract.maxPerTx(upgradedToken.address)).to.be.bignumber.equal(maxPerTx) @@ -1109,60 +1119,73 @@ contract('PrimaryHomeMultiAMBErc20ToErc677', async accounts => { ) }) - it('upgrading token registered correctly on the token migrator contract', async () => { - expect(await tokensMigrator.upgradedTokenAddress(homeToken.address)).to.be.equal(upgradedToken.address) - expect(await tokensMigrator.deprecatedTokenAddress(upgradedToken.address)).to.be.equal(homeToken.address) + it('upgrading token creates correct token pair', async () => { + expect(await contract.homeTokenAddress(token.address)).to.be.equal(upgradedToken.address) + expect(await contract.foreignTokenAddress(upgradedToken.address)).to.be.equal(token.address) }) + // it('upgrading token registered correctly on the token migrator contract', async () => { + // expect(await tokensMigrator.upgradedTokenAddress(homeToken.address)).to.be.equal(upgradedToken.address) + // expect(await tokensMigrator.deprecatedTokenAddress(upgradedToken.address)).to.be.equal(homeToken.address) + // }) + it('cannot relay the deprecated token', async () => { expect(await homeToken.balanceOf(user)).to.be.bignumber.equal(oneEther) await homeToken.approve(contract.address, oneEther, { from: user }).should.be.fulfilled await contract.relayTokens(homeToken.address, halfEther, { from: user }).should.be.rejected }) + it('the upgrade can be reverted by upgrading to the deprecated token again', async () => { + await contract.upgradeToken(upgradedToken.address, homeToken.address, { from: owner }).should.be.fulfilled + expect(await contract.isTokenRegistered(homeToken.address)).to.be.equal(true) + expect(await contract.isTokenRegistered(upgradedToken.address)).to.be.equal(false) + expect(await contract.homeTokenAddress(token.address)).to.be.equal(homeToken.address) + expect(await contract.foreignTokenAddress(homeToken.address)).to.be.equal(token.address) + }) - it('migrateTokens is burning old tokens and mints the new one', async () => { - expect(await homeToken.balanceOf(user)).to.be.bignumber.equal(oneEther) - expect(await upgradedToken.balanceOf(user)).to.be.bignumber.equal(ZERO) - await homeToken.approve(tokensMigrator.address, oneEther, { from: user }).should.be.fulfilled - await tokensMigrator.migrateTokens(homeToken.address, halfEther, { from: user }).should.be.fulfilled - expect(await homeToken.balanceOf(user)).to.be.bignumber.equal(halfEther) - expect(await upgradedToken.balanceOf(user)).to.be.bignumber.equal(halfEther) + // it('migrateTokens is burning old tokens and mints the new one', async () => { + // expect(await homeToken.balanceOf(user)).to.be.bignumber.equal(oneEther) + // expect(await upgradedToken.balanceOf(user)).to.be.bignumber.equal(ZERO) - await tokensMigrator.migrateTokens(homeToken.address, halfEther, { from: user }).should.be.fulfilled - expect(await homeToken.balanceOf(user)).to.be.bignumber.equal(ZERO) - expect(await upgradedToken.balanceOf(user)).to.be.bignumber.equal(oneEther) + // await homeToken.approve(tokensMigrator.address, oneEther, { from: user }).should.be.fulfilled + // await tokensMigrator.migrateTokens(homeToken.address, halfEther, { from: user }).should.be.fulfilled + // expect(await homeToken.balanceOf(user)).to.be.bignumber.equal(halfEther) + // expect(await upgradedToken.balanceOf(user)).to.be.bignumber.equal(halfEther) - await tokensMigrator.migrateTokens(homeToken.address, halfEther, { from: user }).should.be.rejected - }) + // await tokensMigrator.migrateTokens(homeToken.address, halfEther, { from: user }).should.be.fulfilled + // expect(await homeToken.balanceOf(user)).to.be.bignumber.equal(ZERO) + // expect(await upgradedToken.balanceOf(user)).to.be.bignumber.equal(oneEther) - it('cannot migrateTokens not registered token', async () => { - const newToken = await ERC677BridgeToken.new('TEST', 'TST', 18) - await newToken.mint(user, twoEthers, { from: owner }).should.be.fulfilled - expect(await newToken.balanceOf(user)).to.be.bignumber.equal(twoEthers) + // await tokensMigrator.migrateTokens(homeToken.address, halfEther, { from: user }).should.be.rejected + // }) - await newToken.approve(tokensMigrator.address, oneEther, { from: user }).should.be.fulfilled - await tokensMigrator.migrateTokens(newToken.address, halfEther, { from: user }).should.be.rejected - }) + // it('cannot migrateTokens not registered token', async () => { + // const newToken = await ERC677BridgeToken.new('TEST', 'TST', 18) + // await newToken.mint(user, twoEthers, { from: owner }).should.be.fulfilled + // expect(await newToken.balanceOf(user)).to.be.bignumber.equal(twoEthers) - it('cannot migrateTokens with upgraded token', async () => { - expect(await homeToken.balanceOf(user)).to.be.bignumber.equal(oneEther) - expect(await upgradedToken.balanceOf(user)).to.be.bignumber.equal(ZERO) + // await newToken.approve(tokensMigrator.address, oneEther, { from: user }).should.be.fulfilled + // await tokensMigrator.migrateTokens(newToken.address, halfEther, { from: user }).should.be.rejected + // }) - await homeToken.approve(tokensMigrator.address, oneEther, { from: user }).should.be.fulfilled - await tokensMigrator.migrateTokens(homeToken.address, halfEther, { from: user }).should.be.fulfilled - expect(await homeToken.balanceOf(user)).to.be.bignumber.equal(halfEther) - expect(await upgradedToken.balanceOf(user)).to.be.bignumber.equal(halfEther) - }) + // it('cannot migrateTokens with upgraded token', async () => { + // expect(await homeToken.balanceOf(user)).to.be.bignumber.equal(oneEther) + // expect(await upgradedToken.balanceOf(user)).to.be.bignumber.equal(ZERO) - it('cannot call migrateTokens with balance less than value', async () => { - expect(await homeToken.balanceOf(user)).to.be.bignumber.equal(oneEther) - expect(await upgradedToken.balanceOf(user)).to.be.bignumber.equal(ZERO) + // await homeToken.approve(tokensMigrator.address, oneEther, { from: user }).should.be.fulfilled + // await tokensMigrator.migrateTokens(homeToken.address, halfEther, { from: user }).should.be.fulfilled + // expect(await homeToken.balanceOf(user)).to.be.bignumber.equal(halfEther) + // expect(await upgradedToken.balanceOf(user)).to.be.bignumber.equal(halfEther) + // }) - await homeToken.approve(tokensMigrator.address, twoEthers, { from: user }).should.be.fulfilled - await tokensMigrator.migrateTokens(homeToken.address, twoEthers, { from: user }).should.be.rejected - }) + // it('cannot call migrateTokens with balance less than value', async () => { + // expect(await homeToken.balanceOf(user)).to.be.bignumber.equal(oneEther) + // expect(await upgradedToken.balanceOf(user)).to.be.bignumber.equal(ZERO) + + // await homeToken.approve(tokensMigrator.address, twoEthers, { from: user }).should.be.fulfilled + // await tokensMigrator.migrateTokens(homeToken.address, twoEthers, { from: user }).should.be.rejected + // }) }) From f092e9d75634bc55f88a0ac6faa5150251fb01e2 Mon Sep 17 00:00:00 2001 From: Leon Prouger Date: Sun, 13 Jun 2021 22:08:20 +0300 Subject: [PATCH 2/2] Start refactoring multiAMB --- .../PrimaryHomeMultiAMBErc20ToErc677.sol | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/contracts/upgradeable_contracts/multi_amb_erc20_to_erc677/multibridge/PrimaryHomeMultiAMBErc20ToErc677.sol b/contracts/upgradeable_contracts/multi_amb_erc20_to_erc677/multibridge/PrimaryHomeMultiAMBErc20ToErc677.sol index d60bd2fb2..a0acdfc98 100644 --- a/contracts/upgradeable_contracts/multi_amb_erc20_to_erc677/multibridge/PrimaryHomeMultiAMBErc20ToErc677.sol +++ b/contracts/upgradeable_contracts/multi_amb_erc20_to_erc677/multibridge/PrimaryHomeMultiAMBErc20ToErc677.sol @@ -43,24 +43,22 @@ contract PrimaryHomeMultiAMBErc20ToErc677 is HomeMultiAMBErc20ToErc677 { symbol = name; } name = string(abi.encodePacked(name, " on Fuse")); - address homeToken = initializeTokenPair(_token, name, symbol, _decimals); + address homeToken = new TokenProxy(tokenImage(), name, _symbol, _decimals, bridgeContract().sourceChainId()); + IBridgeRegistry(homeToken).addBridge(address(this)); + initializeTokenPair(_token, homeToken, _decimals); _handleBridgedTokens(ERC677(homeToken), _recipient, _value); emit NewTokenRegistered(_token, homeToken); } function initializeTokenPair( address _token, - string _name, - string _symbol, + address _homeToken, uint8 _decimals - ) internal returns (address) { - address homeToken = new TokenProxy(tokenImage(), _name, _symbol, _decimals, bridgeContract().sourceChainId()); - IBridgeRegistry(homeToken).addBridge(address(this)); - _setTokenAddressPair(_token, homeToken); - _initializeTokenBridgeLimits(homeToken, _decimals); - _setFee(HOME_TO_FOREIGN_FEE, homeToken, getFee(HOME_TO_FOREIGN_FEE, address(0))); - _setFee(FOREIGN_TO_HOME_FEE, homeToken, getFee(FOREIGN_TO_HOME_FEE, address(0))); - return homeToken; + ) internal { + _setTokenAddressPair(_token, _homeToken); + _initializeTokenBridgeLimits(_homeToken, _decimals); + _setFee(HOME_TO_FOREIGN_FEE, _homeToken, getFee(HOME_TO_FOREIGN_FEE, address(0))); + _setFee(FOREIGN_TO_HOME_FEE, _homeToken, getFee(FOREIGN_TO_HOME_FEE, address(0))); } /** @@ -93,10 +91,7 @@ contract PrimaryHomeMultiAMBErc20ToErc677 is HomeMultiAMBErc20ToErc677 { uint8 decimals = token.decimals(); address foreignToken = foreignTokenAddress(_deprecatedToken); - _setTokenAddressPair(foreignToken, _upgradedToken); - _initializeTokenBridgeLimits(_upgradedToken, decimals); - _setFee(HOME_TO_FOREIGN_FEE, _upgradedToken, getFee(HOME_TO_FOREIGN_FEE, address(0))); - _setFee(FOREIGN_TO_HOME_FEE, _upgradedToken, getFee(FOREIGN_TO_HOME_FEE, address(0))); + initializeTokenPair(foreignToken, _upgradedToken, decimals); // disable relaying the token to foregin network _setMaxPerTx(_deprecatedToken, uint256(0));