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

LockstakeClipper Callee #43

Merged
merged 25 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8f9505c
add lockstake as a submodule
valiafetisov May 22, 2024
c5a9cf2
update dss-interfaces to the latest commit
valiafetisov May 23, 2024
1332caa
update tests to avoid compilation errors
valiafetisov May 23, 2024
fb62217
add base LockstakeClipperTest
valiafetisov May 23, 2024
f413289
rename to UniswapV2LockstakeCallee
valiafetisov May 23, 2024
4e69fe0
remove hardcoded version in the test.sh
valiafetisov May 27, 2024
8f3efe1
add LockstakeEngineTest
valiafetisov May 27, 2024
4f098c3
rename test and the contract
valiafetisov May 27, 2024
0bf18d3
fix solidity version to 0.6.12 for existing callees
valiafetisov May 27, 2024
0d6aec4
add initial version of UniswapV2LockstakeCallee
valiafetisov May 27, 2024
242ae1c
update math functions
valiafetisov May 27, 2024
2dad8be
adjust callee, add working callee test
valiafetisov May 28, 2024
9e28ecb
add a test case to take the rest of the auction
valiafetisov May 28, 2024
72154bf
test profit address
valiafetisov Jul 2, 2024
6029067
refactor: make uniswap path configurable in tests
valiafetisov Jul 30, 2024
d6d0a7e
determine received gem based on the path
valiafetisov Jul 30, 2024
c5a97a0
Support NGT
valiafetisov Jul 31, 2024
35cb3aa
cleanup tests
valiafetisov Jul 31, 2024
a6f6d59
test minimum dai profit
valiafetisov Jul 31, 2024
84e3501
remove unnecessary changes
valiafetisov Jul 31, 2024
9b5cb11
support NST as destination token
valiafetisov Jul 31, 2024
10fb07b
support both NST and DAI without redeploying
valiafetisov Jul 31, 2024
6a0b414
adressed review
valiafetisov Aug 5, 2024
8ddffec
address review
valiafetisov Aug 13, 2024
e988c49
addressed nits + cleanup
valiafetisov Aug 13, 2024
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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@
[submodule "lib/dss-crop-join"]
path = lib/dss-crop-join
url = https://github.com/makerdao/dss-crop-join
[submodule "lib/lockstake"]
path = lib/lockstake
url = https://github.com/makerdao/lockstake
1 change: 1 addition & 0 deletions lib/lockstake
Submodule lockstake added at 735e1e
4 changes: 2 additions & 2 deletions scripts/test.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#!/usr/bin/env bash

if [[ $# -eq 0 ]] ; then
forge test --use solc:0.6.12 --fork-url "$ETH_RPC_URL"
forge test --fork-url "$ETH_RPC_URL"
else
forge test --use solc:0.6.12 --fork-url "$ETH_RPC_URL" -vvv --match-test ${1}
forge test --fork-url "$ETH_RPC_URL" -vvv --match-test ${1}
fi

2 changes: 1 addition & 1 deletion src/OasisDexCallee.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

pragma solidity >=0.6.12;
pragma solidity 0.6.12;

interface VatLike {
function hope(address) external;
Expand Down
2 changes: 1 addition & 1 deletion src/OneInchCallee.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

pragma solidity >=0.6.12;
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;

interface GemJoinLike {
Expand Down
2 changes: 1 addition & 1 deletion src/PSMCallee.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

pragma solidity >=0.6.12;
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;

interface GemJoinLike {
Expand Down
2 changes: 1 addition & 1 deletion src/UniswapV2Callee.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

pragma solidity >=0.6.12;
pragma solidity 0.6.12;

interface VatLike {
function hope(address) external;
Expand Down
134 changes: 134 additions & 0 deletions src/UniswapV2LockstakeCallee.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright (C) 2020 Maker Ecosystem Growth Holdings, INC.
// Copyright (C) 2024 Dai Foundation
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

pragma solidity ^0.8.21;

interface TokenLike {
function approve(address, uint256) external;
function transfer(address, uint256) external;
function balanceOf(address) external view returns (uint256);
}

interface UniswapV2Router02Like {
function swapExactTokensForTokens(uint256, uint256, address[] calldata, address, uint256) external returns (uint256[] memory);
}

interface DaiJoinLike {
function dai() external view returns (address);
function join(address, uint256) external;
}

interface NstJoinLike {
function nst() external view returns (address);
function join(address, uint256) external;
}

interface MkrNgt {
function mkr() external view returns (address);
function ngt() external view returns (address);
function rate() external view returns (uint256);
function mkrToNgt(address, uint256) external;
}

contract UniswapV2LockstakeCallee {
UniswapV2Router02Like public immutable uniRouter02;
DaiJoinLike public immutable daiJoin;
TokenLike public immutable dai;
NstJoinLike public immutable nstJoin;
TokenLike public immutable nst;
MkrNgt public immutable mkrNgt;
TokenLike public immutable mkr;
TokenLike public immutable ngt;
uint256 public constant RAY = 10 ** 27;

constructor(address uniRouter02_, address daiJoin_, address nstJoin_, address mkrNgt_) {
uniRouter02 = UniswapV2Router02Like(uniRouter02_);

daiJoin = DaiJoinLike(daiJoin_);
dai = TokenLike(daiJoin.dai());
dai.approve(daiJoin_, type(uint256).max);

nstJoin = NstJoinLike(nstJoin_);
nst = TokenLike(nstJoin.nst());
nst.approve(nstJoin_, type(uint256).max);

mkrNgt = MkrNgt(mkrNgt_);
mkr = TokenLike(mkrNgt.mkr());
ngt = TokenLike(mkrNgt.ngt());
}

function divup(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = x != 0 ? ((x - 1) / y) + 1 : 0;
}

function clipperCall(
address sender, // Clipper Caller and DAI/NST delivery address
uint256 dstAmt, // DAI/NST amount to payback [rad]
uint256 gemAmt, // Gem amount received [wad]
bytes calldata data // Extra data needed
) external {
(
address to, // Address to send remaining DAI/NST to
uint256 minProfit, // Minimum profit in DAI/NST to make [wad]
address[] memory path // Uniswap pool path
) = abi.decode(data, (address, uint256, address[]));

// Support NGT
TokenLike gem = mkr;
if (path[0] == address(ngt)) {
gem = ngt;
mkr.approve(address(mkrNgt), gemAmt);
mkrNgt.mkrToNgt(address(this), gemAmt);
gemAmt = gemAmt * mkrNgt.rate();
}

// Approve uniRouter02 to take gem
gem.approve(address(uniRouter02), gemAmt);

// Calculate amount of tokens to Join (as erc20 WAD value)
uint256 amtToJoin = divup(dstAmt, RAY);

// Exchange tokens based on the path (checking the profit is achieved)
uniRouter02.swapExactTokensForTokens(
gemAmt,
amtToJoin + minProfit,
path,
address(this),
block.timestamp
);

// Although Uniswap will accept all gems, this check is a sanity check, just in case
if (gem.balanceOf(address(this)) > 0) {
// Transfer any lingering gem to specified address
gem.transfer(to, gem.balanceOf(address(this)));
}

// Determine destination token
TokenLike dst = TokenLike(path[path.length - 1]);

// Convert tokens bought to internal vat value of the msg.sender of Clipper.take
if (address(dst) == address(dai)) {
daiJoin.join(sender, amtToJoin);
} else if (address(dst) == address(nst)) {
nstJoin.join(sender, amtToJoin);
}

// Transfer remaining tokens to specified address
dst.transfer(to, dst.balanceOf(address(this)));
}
}

2 changes: 1 addition & 1 deletion src/UniswapV2LpTokenCallee.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

pragma solidity >=0.6.12;
pragma solidity 0.6.12;

interface VatLike {
function hope(address) external;
Expand Down
2 changes: 1 addition & 1 deletion src/UniswapV3Callee.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

pragma solidity >=0.6.12;
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;

interface GemJoinLike {
Expand Down
2 changes: 1 addition & 1 deletion src/UniswapV3SplitRouteCallee.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

pragma solidity >=0.6.12;
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;

interface GemJoinLike {
Expand Down
2 changes: 1 addition & 1 deletion src/WstETHCurveUniv3Callee.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

pragma solidity >=0.6.12;
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;

interface GemJoinLike {
Expand Down
Loading
Loading