-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: New UniswapV2LockstakeCallee (#43)
- Loading branch information
1 parent
3b080ec
commit bc4b4eb
Showing
14 changed files
with
603 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule dss-interfaces
updated
26 files
+1 −0 | .gitignore | |
+12 −16 | README.md | |
+3 −0 | src/ERC/GemAbstract.sol | |
+34 −13 | src/Interfaces.sol | |
+26 −0 | src/dss/CureAbstract.sol | |
+1 −1 | src/dss/DaiAbstract.sol | |
+10 −3 | src/dss/ESMAbstract.sol | |
+1 −2 | src/dss/EndAbstract.sol | |
+2 −0 | src/dss/FlapAbstract.sol | |
+24 −0 | src/dss/FlashAbstract.sol | |
+17 −0 | src/dss/GemJoinManagedAbstract.sol | |
+1 −1 | src/dss/JugAbstract.sol | |
+0 −2 | src/dss/LPOsmAbstract.sol | |
+15 −0 | src/dss/LerpAbstract.sol | |
+16 −0 | src/dss/LerpFactoryAbstract.sol | |
+0 −2 | src/dss/OsmAbstract.sol | |
+0 −60 | src/dss/PotHelper.sol | |
+22 −0 | src/dss/PsmAbstract.sol | |
+33 −0 | src/dss/VestAbstract.sol | |
+47 −0 | src/dss/rwa/RwaInputConduitAbstract.sol | |
+12 −0 | src/dss/rwa/RwaJarAbstract.sol | |
+20 −0 | src/dss/rwa/RwaLiquidationOracleAbstract.sol | |
+51 −0 | src/dss/rwa/RwaOutputConduitAbstract.sol | |
+9 −0 | src/dss/rwa/RwaTokenFactoryAbstract.sol | |
+27 −0 | src/dss/rwa/RwaUrnAbstract.sol | |
+8 −0 | src/utils/WardsAbstract.sol |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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))); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.