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

Pref/optimise migration #146

Merged
merged 2 commits into from
Apr 11, 2022
Merged
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
5 changes: 1 addition & 4 deletions contracts/interfaces/IMigration.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ interface IMigration {
/// @notice Method to send assets from migration vault to the vault of the
/// target hub
/// @param meToken Address of meToken
/// @return amountOut Amount of token returned
function finishMigration(address meToken)
external
returns (uint256 amountOut);
function finishMigration(address meToken) external;

/// @notice Method returns bool if migration started
/// @param meToken Address of meToken
Expand Down
46 changes: 20 additions & 26 deletions contracts/migrations/SameAssetTransferMigration.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,26 @@ contract SameAssetTransferMigration is ReentrancyGuard, Vault, IMigration {

mapping(address => SameAssetMigration) private _sameAssetMigration;

modifier onlyDiamond() {
require(msg.sender == diamond, "!diamond");
_;
}

constructor(address _dao, address _diamond) Vault(_dao, _diamond) {}

/// @inheritdoc IMigration
function initMigration(
address meToken,
bytes memory /* encodedArgs */
) external override {
require(msg.sender == diamond, "!diamond");

) external override onlyDiamond {
MeTokenInfo memory meTokenInfo = IMeTokenRegistryFacet(diamond)
.getMeTokenInfo(meToken);
HubInfo memory hubInfo = IHubFacet(diamond).getHubInfo(
meTokenInfo.hubId
);
HubInfo memory targetHubInfo = IHubFacet(diamond).getHubInfo(
meTokenInfo.targetHubId
);

require(hubInfo.asset == targetHubInfo.asset, "asset different");
require(
IHubFacet(diamond).getHubInfo(meTokenInfo.hubId).asset ==
IHubFacet(diamond).getHubInfo(meTokenInfo.targetHubId).asset,
"same asset"
);

_sameAssetMigration[meToken].isMigrating = true;
}
Expand Down Expand Up @@ -75,26 +76,21 @@ contract SameAssetTransferMigration is ReentrancyGuard, Vault, IMigration {
external
override
nonReentrant
returns (uint256 amountOut)
onlyDiamond
{
require(msg.sender == diamond, "!diamond");
SameAssetMigration storage usts = _sameAssetMigration[meToken];
require(usts.isMigrating, "!migrating");

MeTokenInfo memory meTokenInfo = IMeTokenRegistryFacet(diamond)
.getMeTokenInfo(meToken);
HubInfo memory hubInfo = IHubFacet(diamond).getHubInfo(
meTokenInfo.hubId
);
HubInfo memory targetHubInfo = IHubFacet(diamond).getHubInfo(
meTokenInfo.targetHubId
);

if (!usts.started) {
ISingleAssetVault(hubInfo.vault).startMigration(meToken);
usts.started = true;
if (!_sameAssetMigration[meToken].started) {
ISingleAssetVault(
IHubFacet(diamond).getHubInfo(meTokenInfo.hubId).vault
).startMigration(meToken);
}
amountOut = meTokenInfo.balancePooled + meTokenInfo.balanceLocked;
uint256 amountOut = meTokenInfo.balancePooled +
meTokenInfo.balanceLocked;

// Send asset to new vault only if there's a migration vault
IERC20(targetHubInfo.asset).safeTransfer(
Expand All @@ -114,16 +110,14 @@ contract SameAssetTransferMigration is ReentrancyGuard, Vault, IMigration {
usts = _sameAssetMigration[meToken];
}

// Kicks off meToken warmup period
/// @inheritdoc Vault
function isValid(
address meToken,
bytes memory /* encodedArgs */
) external view override returns (bool) {
MeTokenInfo memory meTokenInfo = IMeTokenRegistryFacet(diamond)
.getMeTokenInfo(meToken);
// MeToken not subscribed to a hub
if (meTokenInfo.hubId == 0) return false;
if (IMeTokenRegistryFacet(diamond).getMeTokenInfo(meToken).hubId == 0)
return false;
return true;
}

Expand Down
57 changes: 26 additions & 31 deletions contracts/migrations/UniswapSingleTransferMigration.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ contract UniswapSingleTransferMigration is ReentrancyGuard, Vault, IMigration {
uint24 fee;
// if migration is active and startMigration() has not been triggered
bool started;
// meToken has executed the swap and can finish migrating
bool swapped;
}

mapping(address => UniswapSingleTransfer) private _uniswapSingleTransfers;
Expand All @@ -43,46 +41,48 @@ contract UniswapSingleTransferMigration is ReentrancyGuard, Vault, IMigration {
uint24 public constant MIDFEE = 3000; // 0.3% (Default fee)
uint24 public constant MAXFEE = 1e4; // 1%

modifier onlyDiamond() {
require(msg.sender == diamond, "!diamond");
_;
}

constructor(address _dao, address _diamond) Vault(_dao, _diamond) {}

/// @inheritdoc IMigration
function initMigration(address meToken, bytes memory encodedArgs)
external
override
onlyDiamond
{
require(msg.sender == diamond, "!diamond");

MeTokenInfo memory meTokenInfo = IMeTokenRegistryFacet(diamond)
.getMeTokenInfo(meToken);
HubInfo memory hubInfo = IHubFacet(diamond).getHubInfo(
meTokenInfo.hubId
);
HubInfo memory targetHubInfo = IHubFacet(diamond).getHubInfo(
meTokenInfo.targetHubId
);

require(hubInfo.asset != targetHubInfo.asset, "same asset");
require(
IHubFacet(diamond).getHubInfo(meTokenInfo.hubId).asset !=
IHubFacet(diamond).getHubInfo(meTokenInfo.targetHubId).asset,
"same asset"
);

uint24 fee = abi.decode(encodedArgs, (uint24));
UniswapSingleTransfer storage usts = _uniswapSingleTransfers[meToken];
usts.fee = fee;
_uniswapSingleTransfers[meToken].fee = abi.decode(
encodedArgs,
(uint24)
);
}

/// @inheritdoc IMigration
function poke(address meToken) external override nonReentrant {
// Make sure meToken is in a state of resubscription
UniswapSingleTransfer storage usts = _uniswapSingleTransfers[meToken];
MeTokenInfo memory meTokenInfo = IMeTokenRegistryFacet(diamond)
.getMeTokenInfo(meToken);
HubInfo memory hubInfo = IHubFacet(diamond).getHubInfo(
meTokenInfo.hubId
);

if (
usts.fee != 0 && // this is to ensure the meToken is resubscribing
usts.fee != 0 && // make sure meToken is in a state of resubscription
block.timestamp > meTokenInfo.startTime && // swap can only happen after resubscribe
!usts.started // should skip if already started
) {
ISingleAssetVault(hubInfo.vault).startMigration(meToken);
ISingleAssetVault(
IHubFacet(diamond).getHubInfo(meTokenInfo.hubId).vault
).startMigration(meToken);
usts.started = true;
_swap(meToken);
}
Expand All @@ -93,22 +93,19 @@ contract UniswapSingleTransferMigration is ReentrancyGuard, Vault, IMigration {
external
override
nonReentrant
returns (uint256 amountOut)
onlyDiamond
{
require(msg.sender == diamond, "!diamond");
UniswapSingleTransfer storage usts = _uniswapSingleTransfers[meToken];

MeTokenInfo memory meTokenInfo = IMeTokenRegistryFacet(diamond)
.getMeTokenInfo(meToken);
HubInfo memory hubInfo = IHubFacet(diamond).getHubInfo(
meTokenInfo.hubId
);
HubInfo memory targetHubInfo = IHubFacet(diamond).getHubInfo(
meTokenInfo.targetHubId
);

if (!usts.started) {
ISingleAssetVault(hubInfo.vault).startMigration(meToken);
uint256 amountOut;
if (!_uniswapSingleTransfers[meToken].started) {
ISingleAssetVault(
IHubFacet(diamond).getHubInfo(meTokenInfo.hubId).vault
).startMigration(meToken);
amountOut = _swap(meToken);
} else {
// No swap, amountOut = amountIn
Expand Down Expand Up @@ -206,8 +203,6 @@ contract UniswapSingleTransferMigration is ReentrancyGuard, Vault, IMigration {
sqrtPriceLimitX96: 0
});

usts.swapped = true;

// The call to `exactInputSingle` executes the swap
amountOut = _router.exactInputSingle(params);

Expand Down
6 changes: 1 addition & 5 deletions test/contracts/migrations/UniswapSingleTransfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,9 @@ const setup = async () => {
let encodedVaultDAIArgs: string;
let encodedVaultWETHArgs: string;
let block;
let migrationDetails: [number, boolean, boolean] & {
let migrationDetails: [number, boolean] & {
fee: number;
started: boolean;
swapped: boolean;
};

before(async () => {
Expand Down Expand Up @@ -337,7 +336,6 @@ const setup = async () => {
.to.emit(meTokenRegistry, "UpdateBalances");
migrationDetails = await migration.getDetails(meToken.address);
expect(migrationDetails.started).to.be.equal(true);
expect(migrationDetails.swapped).to.be.equal(true);
});
it("should be able to call when migration already started, but wont run startMigration()", async () => {
const tx = await migration.poke(meToken.address);
Expand Down Expand Up @@ -380,7 +378,6 @@ const setup = async () => {
migrationDetails = await migration.getDetails(meToken.address);
expect(migrationDetails.fee).to.equal(0);
expect(migrationDetails.started).to.equal(false);
expect(migrationDetails.swapped).to.equal(false);
});
it("should revert before endTime", async () => {
let meTokenRegistryDetails = await meTokenRegistry.getMeTokenInfo(
Expand Down Expand Up @@ -455,7 +452,6 @@ const setup = async () => {
migrationDetails = await migration.getDetails(meToken.address);
expect(migrationDetails.fee).to.equal(0);
expect(migrationDetails.started).to.equal(false);
expect(migrationDetails.swapped).to.equal(false);
});

describe("During resubscribe", () => {
Expand Down