add token migration contract
Change-Id: I2bc3fb4d99f5a08452bc2defd3597ec7ad300523
This commit is contained in:
parent
c565152c13
commit
ffcdc3f3f2
|
@ -0,0 +1,68 @@
|
|||
// contracts/Messages.sol
|
||||
// SPDX-License-Identifier: Apache 2
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
|
||||
contract Migrator is ERC20 {
|
||||
IERC20 public fromAsset;
|
||||
IERC20 public toAsset;
|
||||
uint public fromDecimals;
|
||||
uint public toDecimals;
|
||||
|
||||
constructor (
|
||||
address _fromAsset,
|
||||
address _toAsset
|
||||
)
|
||||
// LP shares track the underlying toToken amount
|
||||
ERC20("Token Migration Pool", "Migrator-LP") {
|
||||
fromAsset = IERC20(_fromAsset);
|
||||
toAsset = IERC20(_toAsset);
|
||||
fromDecimals = ERC20(_fromAsset).decimals();
|
||||
toDecimals = ERC20(_toAsset).decimals();
|
||||
}
|
||||
|
||||
// _amount denominated in toAsset
|
||||
function add(uint _amount) external {
|
||||
// deposit toAsset
|
||||
SafeERC20.safeTransferFrom(toAsset, msg.sender, address(this), _amount);
|
||||
// mint LP shares
|
||||
_mint(msg.sender, _amount);
|
||||
}
|
||||
|
||||
// _amount denominated in LP shares
|
||||
function remove(uint _amount) external {
|
||||
// burn LP shares
|
||||
_burn(msg.sender, _amount);
|
||||
// send out toAsset
|
||||
SafeERC20.safeTransfer(toAsset, msg.sender, _amount);
|
||||
}
|
||||
|
||||
// _amount denominated in LP shares
|
||||
function claim(uint _amount) external {
|
||||
// burn LP shares
|
||||
_burn(msg.sender, _amount);
|
||||
// send out fromAsset
|
||||
SafeERC20.safeTransfer(fromAsset, msg.sender, adjustDecimals(toDecimals, fromDecimals, _amount));
|
||||
}
|
||||
|
||||
// _amount denominated in fromToken
|
||||
function migrate(uint _amount) external {
|
||||
// deposit fromAsset
|
||||
SafeERC20.safeTransferFrom(fromAsset, msg.sender, address(this), _amount);
|
||||
// send out toAsset
|
||||
SafeERC20.safeTransfer(toAsset, msg.sender, adjustDecimals(fromDecimals, toDecimals, _amount));
|
||||
}
|
||||
|
||||
function adjustDecimals(uint _fromDecimals, uint _toDecimals, uint _amount) internal pure returns (uint) {
|
||||
if (_fromDecimals > _toDecimals){
|
||||
_amount /= 10 ** (_fromDecimals - _toDecimals);
|
||||
} else if (_fromDecimals < _toDecimals) {
|
||||
_amount *= 10 ** (_toDecimals - _fromDecimals);
|
||||
}
|
||||
return _amount;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
const jsonfile = require('jsonfile');
|
||||
const BigNumber = require('bignumber.js');
|
||||
|
||||
const Migrator = artifacts.require("Migrator");
|
||||
const TokenImplementation = artifacts.require("TokenImplementation");
|
||||
|
||||
contract("Migrator", function (accounts) {
|
||||
var migrator,
|
||||
fromToken,
|
||||
toToken,
|
||||
fromDecimals = 8,
|
||||
toDecimals = 18;
|
||||
|
||||
it("should deploy with the correct values", async function () {
|
||||
fromToken = await TokenImplementation.new();
|
||||
await fromToken.initialize(
|
||||
"TestFrom",
|
||||
"FROM",
|
||||
fromDecimals,
|
||||
0,
|
||||
accounts[0],
|
||||
0,
|
||||
"0x00"
|
||||
)
|
||||
toToken = await TokenImplementation.new();
|
||||
await toToken.initialize(
|
||||
"TestTo",
|
||||
"TO",
|
||||
toDecimals,
|
||||
0,
|
||||
accounts[0],
|
||||
0,
|
||||
"0x00"
|
||||
)
|
||||
|
||||
migrator = await Migrator.new(
|
||||
fromToken.address,
|
||||
toToken.address,
|
||||
);
|
||||
|
||||
assert.equal(await migrator.fromAsset(), fromToken.address)
|
||||
assert.equal(await migrator.toAsset(), toToken.address)
|
||||
assert.equal((await migrator.fromDecimals()).toNumber(), fromDecimals)
|
||||
assert.equal((await migrator.toDecimals()).toNumber(), toDecimals)
|
||||
})
|
||||
|
||||
it("should give out LP tokens 1:1 for a toToken deposit", async function () {
|
||||
await toToken.mint(accounts[0], "1000000000000000000")
|
||||
await toToken.approve(migrator.address, "1000000000000000000")
|
||||
await migrator.add("1000000000000000000")
|
||||
|
||||
|
||||
assert.equal((await toToken.balanceOf(migrator.address)).toString(), "1000000000000000000")
|
||||
assert.equal((await migrator.balanceOf(accounts[0])).toString(), "1000000000000000000")
|
||||
})
|
||||
|
||||
it("should refund toToken for LP tokens", async function () {
|
||||
await migrator.remove("500000000000000000")
|
||||
|
||||
assert.equal((await toToken.balanceOf(migrator.address)).toString(), "500000000000000000")
|
||||
assert.equal((await toToken.balanceOf(accounts[0])).toString(), "500000000000000000")
|
||||
assert.equal((await migrator.balanceOf(accounts[0])).toString(), "500000000000000000")
|
||||
})
|
||||
|
||||
it("should redeem fromToken to toToken adjusting for decimals", async function () {
|
||||
await fromToken.mint(accounts[1], "50000000")
|
||||
await fromToken.approve(migrator.address, "50000000", {
|
||||
from : accounts[1]
|
||||
})
|
||||
await migrator.migrate("50000000", {
|
||||
from : accounts[1]
|
||||
})
|
||||
|
||||
assert.equal((await toToken.balanceOf(accounts[1])).toString(), "500000000000000000")
|
||||
assert.equal((await fromToken.balanceOf(accounts[1])).toString(), "0")
|
||||
assert.equal((await fromToken.balanceOf(migrator.address)).toString(), "50000000")
|
||||
assert.equal((await toToken.balanceOf(migrator.address)).toString(), "0")
|
||||
})
|
||||
|
||||
it("fromToken should be claimable for LP tokens, adjusting for decimals", async function () {
|
||||
await migrator.claim("500000000000000000")
|
||||
|
||||
assert.equal((await fromToken.balanceOf(migrator.address)).toString(), "0")
|
||||
assert.equal((await fromToken.balanceOf(accounts[0])).toString(), "50000000")
|
||||
assert.equal((await migrator.balanceOf(accounts[0])).toString(), "0")
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue