Skip to content

Commit

Permalink
feat: Migrate for another account that has approved (SC-4915) (#6)
Browse files Browse the repository at this point in the history
* feat: Migrate for another account that has approved

* formatting: move allowance assertions

Co-authored-by: Lucas Manuel <[email protected]>
  • Loading branch information
deluca-mike and lucas-manuel authored Mar 7, 2022
1 parent b0160eb commit 3d3f2d6
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 17 deletions.
8 changes: 6 additions & 2 deletions contracts/Migrator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ contract Migrator {
}

function migrate(uint256 amount_) external {
migrate(msg.sender, amount_);
}

function migrate(address owner, uint256 amount_) public {
require(amount_ > 0, "M:M:ZERO_AMOUNT");

require(ERC20Helper.transferFrom(oldToken, msg.sender, address(this), amount_), "M:M:TRANSFER_FROM_FAILED");
require(ERC20Helper.transfer(newToken, msg.sender, amount_), "M:M:TRANSFER_FAILED");
require(ERC20Helper.transferFrom(oldToken, owner, address(this), amount_), "M:M:TRANSFER_FROM_FAILED");
require(ERC20Helper.transfer(newToken, owner, amount_), "M:M:TRANSFER_FAILED");
}

}
8 changes: 4 additions & 4 deletions contracts/interfaces/IMigrator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@ pragma solidity 0.8.7;
interface IMigrator {

/**
* @dev Get address of oldToken.
* @dev Get address of oldToken.
* @return oldToken_ The address of new token.
*/
function oldToken() external view returns (address oldToken_);

/**
* @dev Get address of newToken.
* @dev Get address of newToken.
* @return newToken_ The address of new token.
*/
function newToken() external view returns (address newToken_);

/**
* @dev Exchange the oldToken for the same amount of newToken.
* @param amount_ The amount of oldToken to swap for newToken.
* @dev Exchange the oldToken for the same amount of newToken.
* @param amount_ The amount of oldToken to swap for newToken.
*/
function migrate(uint256 amount_) external;

Expand Down
66 changes: 56 additions & 10 deletions contracts/test/Migrator.t.sol
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.8.7;

import { TestUtils } from "../../modules/contract-test-utils/contracts/test.sol";
import { IERC20 } from "../../modules/erc20/contracts/interfaces/IERC20.sol";

import { TestUtils } from "../../modules/contract-test-utils/contracts/test.sol";
import { MockERC20 } from "../../modules/erc20/contracts/test/mocks/MockERC20.sol";

import { Migrator } from "../Migrator.sol";

contract SomeAccount {

function approve(address token_, address spender_, uint256 amount_) external {
IERC20(token_).approve(spender_, amount_);
}

}

contract MigratorTest is TestUtils {

uint256 public constant OLD_SUPPLY = 10_000_000 ether;
Expand Down Expand Up @@ -34,21 +43,51 @@ contract MigratorTest is TestUtils {
// Approve
oldToken.approve(address(migrator), amount_);

assertEq(oldToken.allowance(address(this), address(migrator)), amount_);

assertEq(oldToken.balanceOf(address(this)), amount_);
assertEq(oldToken.balanceOf(address(migrator)), 0);
assertEq(oldToken.allowance(address(this), address(migrator)), amount_);
assertEq(newToken.balanceOf(address(this)), 0);
assertEq(newToken.balanceOf(address(migrator)), OLD_SUPPLY);

migrator.migrate(amount_);

assertEq(oldToken.allowance(address(this), address(migrator)), 0);

assertEq(oldToken.balanceOf(address(this)), 0);
assertEq(oldToken.balanceOf(address(migrator)), amount_);
assertEq(oldToken.allowance(address(this), address(migrator)), 0);
assertEq(newToken.balanceOf(address(this)), amount_);
assertEq(newToken.balanceOf(address(migrator)), OLD_SUPPLY - amount_);
}

function test_migrationForSpecifiedOwner(uint256 amount_) external {
amount_ = constrictToRange(amount_, 1, OLD_SUPPLY);

SomeAccount someAccount = new SomeAccount();

// Mint amount of old token
oldToken.mint(address(someAccount), amount_);

// Approve
someAccount.approve(address(oldToken), address(migrator), amount_);

assertEq(oldToken.allowance(address(someAccount), address(migrator)), amount_);

assertEq(oldToken.balanceOf(address(someAccount)), amount_);
assertEq(oldToken.balanceOf(address(migrator)), 0);
assertEq(newToken.balanceOf(address(someAccount)), 0);
assertEq(newToken.balanceOf(address(migrator)), OLD_SUPPLY);

migrator.migrate(address(someAccount), amount_);

assertEq(oldToken.allowance(address(someAccount), address(migrator)), 0);

assertEq(oldToken.balanceOf(address(someAccount)), 0);
assertEq(oldToken.balanceOf(address(migrator)), amount_);
assertEq(newToken.balanceOf(address(someAccount)), amount_);
assertEq(newToken.balanceOf(address(migrator)), OLD_SUPPLY - amount_);
}

function test_partialMigration(uint256 amount_, uint256 partialAmount_) external {
amount_ = constrictToRange(amount_, 2, OLD_SUPPLY);
partialAmount_ = constrictToRange(partialAmount_, 1, amount_ - 1);
Expand All @@ -59,17 +98,19 @@ contract MigratorTest is TestUtils {
// Approve partial
oldToken.approve(address(migrator), partialAmount_);

assertEq(oldToken.allowance(address(this), address(migrator)), partialAmount_);

assertEq(oldToken.balanceOf(address(this)), amount_);
assertEq(oldToken.balanceOf(address(migrator)), 0);
assertEq(oldToken.allowance(address(this), address(migrator)), partialAmount_);
assertEq(newToken.balanceOf(address(this)), 0);
assertEq(newToken.balanceOf(address(migrator)), OLD_SUPPLY);

migrator.migrate(partialAmount_);

assertEq(oldToken.allowance(address(this), address(migrator)), 0);

assertEq(oldToken.balanceOf(address(this)), amount_ - partialAmount_);
assertEq(oldToken.balanceOf(address(migrator)), partialAmount_);
assertEq(oldToken.allowance(address(this), address(migrator)), 0);
assertEq(newToken.balanceOf(address(this)), partialAmount_);
assertEq(newToken.balanceOf(address(migrator)), OLD_SUPPLY - partialAmount_);

Expand All @@ -79,9 +120,10 @@ contract MigratorTest is TestUtils {

migrator.migrate(remaining);

assertEq(oldToken.allowance(address(this), address(migrator)), 0);

assertEq(oldToken.balanceOf(address(this)), 0);
assertEq(oldToken.balanceOf(address(migrator)), amount_);
assertEq(oldToken.allowance(address(this), address(migrator)), 0);
assertEq(newToken.balanceOf(address(this)), amount_);
assertEq(newToken.balanceOf(address(migrator)), OLD_SUPPLY - amount_);
}
Expand All @@ -99,9 +141,10 @@ contract MigratorTest is TestUtils {

migrator.migrate(amount_);

assertEq(oldToken.allowance(address(this), address(migrator)), 0);

assertEq(oldToken.balanceOf(address(this)), 0);
assertEq(oldToken.balanceOf(address(migrator)), amount_);
assertEq(oldToken.allowance(address(this), address(migrator)), 0);
assertEq(newToken.balanceOf(address(this)), amount_);
assertEq(newToken.balanceOf(address(migrator)), OLD_SUPPLY - amount_);
}
Expand All @@ -120,9 +163,10 @@ contract MigratorTest is TestUtils {

migrator.migrate(amount_);

assertEq(oldToken.allowance(address(this), address(migrator)), 0);

assertEq(oldToken.balanceOf(address(this)), 0);
assertEq(oldToken.balanceOf(address(migrator)), amount_);
assertEq(oldToken.allowance(address(this), address(migrator)), 0);
assertEq(newToken.balanceOf(address(this)), amount_);
assertEq(newToken.balanceOf(address(migrator)), OLD_SUPPLY - amount_);
}
Expand All @@ -142,9 +186,10 @@ contract MigratorTest is TestUtils {

migrator.migrate(amount_);

assertEq(oldToken.allowance(address(this), address(migrator)), 0);

assertEq(oldToken.balanceOf(address(this)), 0);
assertEq(oldToken.balanceOf(address(migrator)), amount_);
assertEq(oldToken.allowance(address(this), address(migrator)), 0);
assertEq(newToken.balanceOf(address(this)), amount_);
assertEq(newToken.balanceOf(address(migrator)), OLD_SUPPLY - amount_);
}
Expand All @@ -168,9 +213,10 @@ contract MigratorTest is TestUtils {

migrator.migrate(amount_);

assertEq(oldToken.allowance(address(this), address(migrator)), 0);

assertEq(oldToken.balanceOf(address(this)), 0);
assertEq(oldToken.balanceOf(address(migrator)), amount_);
assertEq(oldToken.allowance(address(this), address(migrator)), 0);
assertEq(newToken.balanceOf(address(this)), amount_);
assertEq(newToken.balanceOf(address(migrator)), 0);
}
Expand Down
2 changes: 1 addition & 1 deletion modules/erc20

0 comments on commit 3d3f2d6

Please sign in to comment.