From 3d49ab895cf4a13d26d3331a004aacb7858d9877 Mon Sep 17 00:00:00 2001 From: Vedran Bidin Date: Wed, 3 Jul 2024 17:35:09 +0300 Subject: [PATCH] feat: Replace `owner` with `recipient` (SC-17193) (#23) * feat: replace owner with recipient when migrating * test: add additional unit test --- contracts/Migrator.sol | 6 ++-- contracts/interfaces/IMigrator.sol | 8 +++--- tests/Migrator.t.sol | 45 +++++++++++++++++++++++++++--- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/contracts/Migrator.sol b/contracts/Migrator.sol index c76f8eb..964bf0f 100644 --- a/contracts/Migrator.sol +++ b/contracts/Migrator.sol @@ -33,14 +33,14 @@ contract Migrator is IMigrator { newTokenAmount_ = migrate(msg.sender, oldTokenAmount_); } - function migrate(address owner_, uint256 oldTokenAmount_) public override returns (uint256 newTokenAmount_) { + function migrate(address recipient_, uint256 oldTokenAmount_) public override returns (uint256 newTokenAmount_) { require(active, "M:M:INACTIVE"); require(oldTokenAmount_ != uint256(0), "M:M:ZERO_AMOUNT"); newTokenAmount_ = oldTokenAmount_ * tokenSplitScalar; - require(ERC20Helper.transferFrom(oldToken, owner_, address(this), oldTokenAmount_), "M:M:TRANSFER_FROM_FAILED"); - require(ERC20Helper.transfer(newToken, owner_, newTokenAmount_), "M:M:TRANSFER_FAILED"); + require(ERC20Helper.transferFrom(oldToken, msg.sender, address(this), oldTokenAmount_), "M:M:TRANSFER_FROM_FAILED"); + require(ERC20Helper.transfer(newToken, recipient_, newTokenAmount_), "M:M:TRANSFER_FAILED"); } function setActive(bool active_) external override { diff --git a/contracts/interfaces/IMigrator.sol b/contracts/interfaces/IMigrator.sol index 801887c..b95d3f4 100644 --- a/contracts/interfaces/IMigrator.sol +++ b/contracts/interfaces/IMigrator.sol @@ -28,19 +28,19 @@ interface IMigrator { function oldToken() external view returns (address oldToken_); /** - * @dev Exchange the oldToken for the same amount of newToken. + * @dev Exchange the oldToken for the same amount of newToken. * @param oldTokenAmount_ The amount of oldToken to swap for newToken. * @return newTokenAmount_ The amount of newToken received. */ function migrate(uint256 oldTokenAmount_) external returns (uint256 newTokenAmount_); /** - * @dev Exchange the oldToken for the same amount of newToken. - * @param owner_ The address of the owner of the oldToken. + * @dev Exchange the oldToken for the same amount of newToken. + * @param recipient_ The address of the recipient of the newToken. * @param oldTokenAmount_ The amount of oldToken to swap for newToken. * @return newTokenAmount_ The amount of newToken received. */ - function migrate(address owner_, uint256 oldTokenAmount_) external returns (uint256 newTokenAmount_); + function migrate(address recipient_, uint256 oldTokenAmount_) external returns (uint256 newTokenAmount_); /** * @dev Set the migrator to active or inactive. diff --git a/tests/Migrator.t.sol b/tests/Migrator.t.sol index 526a952..d738846 100644 --- a/tests/Migrator.t.sol +++ b/tests/Migrator.t.sol @@ -106,8 +106,12 @@ contract MigratorTest is Test { uint256 internal constant SCALAR = 10; uint256 internal constant OLD_SUPPLY = 10_000_000e18; - address operationalAdmin = makeAddr("operationalAdmin"); address account = makeAddr("account"); + address operationalAdmin = makeAddr("operationalAdmin"); + address recipient = makeAddr("recipient"); + address sender = makeAddr("sender"); + + uint256 amount = 100e18; Migrator internal _migrator; MockERC20 internal _oldToken; @@ -158,6 +162,32 @@ contract MigratorTest is Test { _migrator.migrate(1); } + function test_migrate_recipient() external { + _oldToken.mint(address(sender), amount); + + vm.prank(sender); + _oldToken.approve(address(_migrator), amount); + + assertEq(_oldToken.balanceOf(address(sender)), amount); + assertEq(_oldToken.balanceOf(address(_migrator)), 0); + assertEq(_oldToken.balanceOf(address(recipient)), 0); + + assertEq(_newToken.balanceOf(address(sender)), 0); + assertEq(_newToken.balanceOf(address(_migrator)), OLD_SUPPLY * SCALAR); + assertEq(_newToken.balanceOf(address(recipient)), 0); + + vm.prank(sender); + _migrator.migrate(address(recipient), amount); + + assertEq(_oldToken.balanceOf(address(sender)), 0); + assertEq(_oldToken.balanceOf(address(_migrator)), amount); + assertEq(_oldToken.balanceOf(address(recipient)), 0); + + assertEq(_newToken.balanceOf(address(sender)), 0); + assertEq(_newToken.balanceOf(address(_migrator)), (OLD_SUPPLY - amount) * SCALAR); + assertEq(_newToken.balanceOf(address(recipient)), amount * SCALAR); + } + function testFuzz_migrate_insufficientApproval(uint256 amount_) external { amount_ = bound(amount_, 1, OLD_SUPPLY); @@ -266,7 +296,7 @@ contract MigratorTest is Test { assertEq(_newToken.balanceOf(address(_migrator)), (OLD_SUPPLY * SCALAR) - newAmount); } - function testFuzz_migration_specifiedOwner(uint256 amount_) external { + function testFuzz_migration_specifiedRecipient(uint256 amount_) external { amount_ = bound(amount_, 1, OLD_SUPPLY); uint256 newAmount = amount_ * SCALAR; @@ -282,17 +312,24 @@ contract MigratorTest is Test { assertEq(_oldToken.balanceOf(address(account)), amount_); assertEq(_oldToken.balanceOf(address(_migrator)), 0); + assertEq(_oldToken.balanceOf(address(recipient)), 0); + assertEq(_newToken.balanceOf(address(account)), 0); assertEq(_newToken.balanceOf(address(_migrator)), OLD_SUPPLY * SCALAR); + assertEq(_newToken.balanceOf(address(recipient)), 0); - _migrator.migrate(address(account), amount_); + vm.prank(account); + _migrator.migrate(address(recipient), amount_); assertEq(_oldToken.allowance(address(account), address(_migrator)), 0); assertEq(_oldToken.balanceOf(address(account)), 0); assertEq(_oldToken.balanceOf(address(_migrator)), amount_); - assertEq(_newToken.balanceOf(address(account)), newAmount); + assertEq(_oldToken.balanceOf(address(recipient)), 0); + + assertEq(_newToken.balanceOf(address(account)), 0); assertEq(_newToken.balanceOf(address(_migrator)), (OLD_SUPPLY * SCALAR) - newAmount); + assertEq(_newToken.balanceOf(address(recipient)), newAmount); } function testFuzz_migrate_partialMigration(uint256 amount_, uint256 partialAmount_) external {