Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change upgrateToken functionality #5

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
}

/**
Expand All @@ -81,26 +79,26 @@ 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);

initializeTokenPair(foreignToken, _upgradedToken, decimals);

// 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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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
// })
})


Expand Down