mirror of
https://github.com/Instadapp/smart-contract.git
synced 2024-07-29 22:08:07 +00:00
added mkr swap and fixed few bugs in migrate.
This commit is contained in:
parent
73e47ea28e
commit
8dffe62a18
|
@ -46,6 +46,11 @@ interface UniswapExchange {
|
||||||
uint256 deadline,
|
uint256 deadline,
|
||||||
address tokenAddr
|
address tokenAddr
|
||||||
) external returns (uint256 tokensSold);
|
) external returns (uint256 tokensSold);
|
||||||
|
function ethToTokenSwapOutput(uint256 tokensBought, uint256 deadline) external payable returns (uint256 ethSold);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UniswapFactoryInterface {
|
||||||
|
function getExchange(address token) external view returns (address exchange);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MCDInterface {
|
interface MCDInterface {
|
||||||
|
@ -58,6 +63,16 @@ interface PoolInterface {
|
||||||
function paybackToken(address[] calldata ctknAddr, bool isCompound) external payable;
|
function paybackToken(address[] calldata ctknAddr, bool isCompound) external payable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface OtcInterface {
|
||||||
|
function getPayAmount(address, address, uint) external view returns (uint);
|
||||||
|
function buyAllAmount(
|
||||||
|
address,
|
||||||
|
uint,
|
||||||
|
address,
|
||||||
|
uint
|
||||||
|
) external;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
contract DSMath {
|
contract DSMath {
|
||||||
|
|
||||||
|
@ -112,6 +127,20 @@ contract Helpers is DSMath {
|
||||||
dai = 0x448a5065aeBB8E423F0896E6c5D525C040f59af3;
|
dai = 0x448a5065aeBB8E423F0896E6c5D525C040f59af3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev get Compound WETH Address
|
||||||
|
*/
|
||||||
|
function getWETHAddress() public pure returns (address wethAddr) {
|
||||||
|
wethAddr = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; // main
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev get Compound OTC Address
|
||||||
|
*/
|
||||||
|
function getOtcAddress() public pure returns (address otcAddr) {
|
||||||
|
otcAddr = 0x39755357759cE0d7f32dC8dC45414CCa409AE24e; // main
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev get uniswap MKR exchange
|
* @dev get uniswap MKR exchange
|
||||||
*/
|
*/
|
||||||
|
@ -126,6 +155,13 @@ contract Helpers is DSMath {
|
||||||
ude = 0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14;
|
ude = 0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev get uniswap factory
|
||||||
|
*/
|
||||||
|
function getUniswapFactory() public pure returns (address addr) {
|
||||||
|
addr = 0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev get InstaDApp Liquidity Address
|
* @dev get InstaDApp Liquidity Address
|
||||||
*/
|
*/
|
||||||
|
@ -134,10 +170,14 @@ contract Helpers is DSMath {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev get CDP bytes by CDP ID
|
* @dev setting allowance to compound for the "user proxy" if required
|
||||||
*/
|
*/
|
||||||
function getCDPBytes(uint cdpNum) public pure returns (bytes32 cup) {
|
function setApproval(address erc20, uint srcAmt, address to) internal {
|
||||||
cup = bytes32(cdpNum);
|
TokenInterface erc20Contract = TokenInterface(erc20);
|
||||||
|
uint tokenAllowance = erc20Contract.allowance(address(this), to);
|
||||||
|
if (srcAmt > tokenAllowance) {
|
||||||
|
erc20Contract.approve(to, 2**255);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -149,7 +189,41 @@ contract SCDResolver is Helpers {
|
||||||
cup = TubInterface(getSaiTubAddress()).open();
|
cup = TubInterface(getSaiTubAddress()).open();
|
||||||
}
|
}
|
||||||
|
|
||||||
function lock(bytes32 cup, uint jam) public payable {
|
function wipe(bytes32 cup, uint _wad) internal {
|
||||||
|
if (_wad > 0) {
|
||||||
|
TubInterface tub = TubInterface(getSaiTubAddress());
|
||||||
|
TokenInterface dai = tub.sai();
|
||||||
|
TokenInterface mkr = tub.gov();
|
||||||
|
|
||||||
|
(address lad,,,) = tub.cups(cup);
|
||||||
|
require(lad == address(this), "cup-not-owned");
|
||||||
|
|
||||||
|
setAllowance(dai, getSaiTubAddress());
|
||||||
|
setAllowance(mkr, getSaiTubAddress());
|
||||||
|
|
||||||
|
tub.wipe(cup, _wad);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function free(bytes32 cup, uint jam) internal {
|
||||||
|
if (jam > 0) {
|
||||||
|
address tubAddr = getSaiTubAddress();
|
||||||
|
|
||||||
|
TubInterface tub = TubInterface(tubAddr);
|
||||||
|
TokenInterface peth = tub.skr();
|
||||||
|
|
||||||
|
uint ink = rdiv(jam, tub.per());
|
||||||
|
ink = rmul(ink, tub.per()) <= jam ? ink : ink - 1;
|
||||||
|
tub.free(cup, ink);
|
||||||
|
|
||||||
|
setAllowance(peth, tubAddr);
|
||||||
|
|
||||||
|
tub.exit(ink);
|
||||||
|
// weth.withdraw(freeJam); // No need because we will lock it in small cdp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function lock(bytes32 cup, uint jam) internal {
|
||||||
if (jam > 0) {
|
if (jam > 0) {
|
||||||
address tubAddr = getSaiTubAddress();
|
address tubAddr = getSaiTubAddress();
|
||||||
|
|
||||||
|
@ -160,7 +234,7 @@ contract SCDResolver is Helpers {
|
||||||
(address lad,,,) = tub.cups(cup);
|
(address lad,,,) = tub.cups(cup);
|
||||||
require(lad == address(this), "cup-not-owned");
|
require(lad == address(this), "cup-not-owned");
|
||||||
|
|
||||||
weth.deposit.value(jam)();
|
// weth.deposit.value(msg.value)(); // no need because withdrawn Weth is not convert back
|
||||||
|
|
||||||
uint ink = rdiv(jam, tub.per());
|
uint ink = rdiv(jam, tub.per());
|
||||||
ink = rmul(ink, tub.per()) <= jam ? ink : ink - 1;
|
ink = rmul(ink, tub.per()) <= jam ? ink : ink - 1;
|
||||||
|
@ -173,73 +247,13 @@ contract SCDResolver is Helpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function free(bytes32 cup, uint jam) public {
|
function draw(bytes32 cup, uint _wad) internal {
|
||||||
if (jam > 0) {
|
|
||||||
address tubAddr = getSaiTubAddress();
|
|
||||||
|
|
||||||
TubInterface tub = TubInterface(tubAddr);
|
|
||||||
TokenInterface peth = tub.skr();
|
|
||||||
TokenInterface weth = tub.gem();
|
|
||||||
|
|
||||||
uint ink = rdiv(jam, tub.per());
|
|
||||||
ink = rmul(ink, tub.per()) <= jam ? ink : ink - 1;
|
|
||||||
tub.free(cup, ink);
|
|
||||||
|
|
||||||
setAllowance(peth, tubAddr);
|
|
||||||
|
|
||||||
tub.exit(ink);
|
|
||||||
uint freeJam = weth.balanceOf(address(this)); // withdraw possible previous stuck WETH as well
|
|
||||||
weth.withdraw(freeJam);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function draw(bytes32 cup, uint _wad) public {
|
|
||||||
if (_wad > 0) {
|
if (_wad > 0) {
|
||||||
TubInterface tub = TubInterface(getSaiTubAddress());
|
TubInterface tub = TubInterface(getSaiTubAddress());
|
||||||
tub.draw(cup, _wad);
|
tub.draw(cup, _wad);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function wipe(bytes32 cup, uint _wad) public {
|
|
||||||
if (_wad > 0) {
|
|
||||||
TubInterface tub = TubInterface(getSaiTubAddress());
|
|
||||||
UniswapExchange daiEx = UniswapExchange(getUniswapDAIExchange());
|
|
||||||
UniswapExchange mkrEx = UniswapExchange(getUniswapMKRExchange());
|
|
||||||
TokenInterface dai = tub.sai();
|
|
||||||
TokenInterface mkr = tub.gov();
|
|
||||||
|
|
||||||
(address lad,,,) = tub.cups(cup);
|
|
||||||
require(lad == address(this), "cup-not-owned");
|
|
||||||
|
|
||||||
setAllowance(dai, getSaiTubAddress());
|
|
||||||
setAllowance(mkr, getSaiTubAddress());
|
|
||||||
setAllowance(dai, getUniswapDAIExchange());
|
|
||||||
|
|
||||||
(bytes32 val, bool ok) = tub.pep().peek();
|
|
||||||
|
|
||||||
//Check Thrilok
|
|
||||||
// MKR required for wipe = Stability fees accrued in Dai / MKRUSD value
|
|
||||||
uint mkrFee = wdiv(rmul(_wad, rdiv(tub.rap(cup), tub.tab(cup))), uint(val));
|
|
||||||
|
|
||||||
uint daiFeeAmt = daiEx.getTokenToEthOutputPrice(mkrEx.getEthToTokenOutputPrice(mkrFee));
|
|
||||||
uint daiAmt = add(_wad, daiFeeAmt);
|
|
||||||
require(dai.transferFrom(msg.sender, address(this), daiAmt), "not-approved-yet");
|
|
||||||
|
|
||||||
if (ok && val != 0) {
|
|
||||||
daiEx.tokenToTokenSwapOutput(
|
|
||||||
mkrFee,
|
|
||||||
daiAmt,
|
|
||||||
uint(999000000000000000000),
|
|
||||||
uint(1899063809), // 6th March 2030 GMT // no logic
|
|
||||||
address(mkr)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
tub.wipe(cup, _wad);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setAllowance(TokenInterface _token, address _spender) private {
|
function setAllowance(TokenInterface _token, address _spender) private {
|
||||||
if (_token.allowance(address(this), _spender) != uint(-1)) {
|
if (_token.allowance(address(this), _spender) != uint(-1)) {
|
||||||
_token.approve(_spender, uint(-1));
|
_token.approve(_spender, uint(-1));
|
||||||
|
@ -249,7 +263,53 @@ contract SCDResolver is Helpers {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
contract MCDResolver is SCDResolver {
|
contract MkrResolver is SCDResolver {
|
||||||
|
function swapToMkrOtc(address tokenAddr, uint govFee) internal {
|
||||||
|
TokenInterface mkr = TubInterface(getSaiTubAddress()).gov();
|
||||||
|
uint payAmt = OtcInterface(getOtcAddress()).getPayAmount(tokenAddr, address(mkr), govFee);
|
||||||
|
if (tokenAddr == getWETHAddress()) {
|
||||||
|
TokenInterface weth = TokenInterface(getWETHAddress());
|
||||||
|
weth.deposit.value(payAmt)();
|
||||||
|
} else {
|
||||||
|
require(TokenInterface(tokenAddr).transferFrom(msg.sender, address(this), payAmt), "Tranfer-failed");
|
||||||
|
}
|
||||||
|
setApproval(tokenAddr, payAmt, getOtcAddress());
|
||||||
|
OtcInterface(getOtcAddress()).buyAllAmount(
|
||||||
|
address(mkr),
|
||||||
|
govFee,
|
||||||
|
tokenAddr,
|
||||||
|
payAmt
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function swapToMkrUniswap(address tokenAddr, uint govFee) internal {
|
||||||
|
UniswapExchange mkrEx = UniswapExchange(getUniswapMKRExchange());
|
||||||
|
address uniSwapFactoryAddr = 0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95;
|
||||||
|
TokenInterface mkr = TubInterface(getSaiTubAddress()).gov();
|
||||||
|
|
||||||
|
if (tokenAddr == getWETHAddress()) {
|
||||||
|
uint ethNeeded = mkrEx.getEthToTokenOutputPrice(govFee);
|
||||||
|
mkrEx.ethToTokenSwapOutput.value(ethNeeded)(govFee, uint(1899063809));
|
||||||
|
} else {
|
||||||
|
address buyTknExAddr = UniswapFactoryInterface(uniSwapFactoryAddr).getExchange(tokenAddr);
|
||||||
|
UniswapExchange buyTknEx = UniswapExchange(buyTknExAddr);
|
||||||
|
uint tknAmt = buyTknEx.getTokenToEthOutputPrice(mkrEx.getEthToTokenOutputPrice(govFee)); //Check thrilok is this correct
|
||||||
|
require(TokenInterface(tokenAddr).transferFrom(msg.sender, address(this), tknAmt), "not-approved-yet");
|
||||||
|
setApproval(tokenAddr, tknAmt, buyTknExAddr);
|
||||||
|
buyTknEx.tokenToTokenSwapOutput(
|
||||||
|
govFee,
|
||||||
|
tknAmt,
|
||||||
|
uint(999000000000000000000),
|
||||||
|
uint(1899063809), // 6th March 2030 GMT // no logic
|
||||||
|
address(mkr)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
contract MCDResolver is MkrResolver {
|
||||||
function swapDaiToSai(
|
function swapDaiToSai(
|
||||||
address payable scdMcdMigration, // Migration contract address
|
address payable scdMcdMigration, // Migration contract address
|
||||||
uint wad // Amount to swap
|
uint wad // Amount to swap
|
||||||
|
@ -268,7 +328,6 @@ contract MCDResolver is SCDResolver {
|
||||||
address payable scdMcdMigration, // Migration contract address
|
address payable scdMcdMigration, // Migration contract address
|
||||||
bytes32 cup, // SCD CDP Id to migrate
|
bytes32 cup, // SCD CDP Id to migrate
|
||||||
address payGem // Token address (only if gov fee will be paid with another token)
|
address payGem // Token address (only if gov fee will be paid with another token)
|
||||||
// uint maxPayAmt // Max amount of payGem to sell for govFee needed (only if gov fee will be paid with another token)
|
|
||||||
) internal returns (uint cdp)
|
) internal returns (uint cdp)
|
||||||
{
|
{
|
||||||
TubInterface tub = TubInterface(getSaiTubAddress());
|
TubInterface tub = TubInterface(getSaiTubAddress());
|
||||||
|
@ -281,10 +340,8 @@ contract MCDResolver is SCDResolver {
|
||||||
uint govFee = wdiv(tub.rap(cup), uint(val));
|
uint govFee = wdiv(tub.rap(cup), uint(val));
|
||||||
|
|
||||||
if (payGem != address(0)) {
|
if (payGem != address(0)) {
|
||||||
// Swap ETH to WETH => WETH TO MKR
|
swapToMkrOtc(payGem, govFee);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Else get MKR from the user's wallet and transfer to Migration contract
|
|
||||||
require(tub.gov().transferFrom(msg.sender, address(this), govFee), "transfer-failed");
|
require(tub.gov().transferFrom(msg.sender, address(this), govFee), "transfer-failed");
|
||||||
}
|
}
|
||||||
require(tub.gov().transfer(address(scdMcdMigration), govFee), "transfer-failed");
|
require(tub.gov().transfer(address(scdMcdMigration), govFee), "transfer-failed");
|
||||||
|
@ -296,6 +353,7 @@ contract MCDResolver is SCDResolver {
|
||||||
|
|
||||||
|
|
||||||
contract MigrateResolver is MCDResolver {
|
contract MigrateResolver is MCDResolver {
|
||||||
|
event LogMigrate(uint scdCdp, uint toConvert, address payFeeWith, uint mcdCdp);
|
||||||
function migrate(
|
function migrate(
|
||||||
bytes32 scdCup,
|
bytes32 scdCup,
|
||||||
// uint mcdCDP, for merge
|
// uint mcdCDP, for merge
|
||||||
|
@ -307,13 +365,14 @@ contract MigrateResolver is MCDResolver {
|
||||||
TubInterface tub = TubInterface(getSaiTubAddress());
|
TubInterface tub = TubInterface(getSaiTubAddress());
|
||||||
uint _jam = rmul(tub.ink(scdCup), tub.per());
|
uint _jam = rmul(tub.ink(scdCup), tub.per());
|
||||||
uint _wad = tub.tab(scdCup);
|
uint _wad = tub.tab(scdCup);
|
||||||
if (toConvert >= 10**18) {
|
if (toConvert < 10**18) {
|
||||||
uint initialPoolBal = sub(getPoolAddress().balance, 10000000000);
|
uint initialPoolBal = sub(getPoolAddress().balance, 10000000000);
|
||||||
bytes32 splitCup = TubInterface(getSaiTubAddress()).open();
|
bytes32 splitCup = TubInterface(getSaiTubAddress()).open();
|
||||||
|
|
||||||
_jam = wmul(_jam, toConvert);
|
_jam = wmul(_jam, toConvert);
|
||||||
_wad = wmul(_wad, toConvert);
|
_wad = wmul(_wad, toConvert);
|
||||||
|
|
||||||
|
|
||||||
uint[] memory _wadArr = new uint[](1);
|
uint[] memory _wadArr = new uint[](1);
|
||||||
_wadArr[0] = _wad;
|
_wadArr[0] = _wad;
|
||||||
|
|
||||||
|
@ -323,13 +382,21 @@ contract MigrateResolver is MCDResolver {
|
||||||
// Get liquidity assets to payback user wallet borrowed assets
|
// Get liquidity assets to payback user wallet borrowed assets
|
||||||
PoolInterface(getPoolAddress()).accessToken(addrArr, _wadArr, false);
|
PoolInterface(getPoolAddress()).accessToken(addrArr, _wadArr, false);
|
||||||
|
|
||||||
|
(bytes32 val, bool ok) = tub.pep().peek();
|
||||||
|
|
||||||
|
if (ok && val != 0) {
|
||||||
|
// MKR required for wipe = Stability fees accrued in Dai / MKRUSD value
|
||||||
|
uint mkrFee = wdiv(rmul(_wad, rdiv(tub.rap(scdCup), tub.tab(scdCup))), uint(val));
|
||||||
|
swapToMkrUniswap(payFeeWith, mkrFee);
|
||||||
|
}
|
||||||
|
|
||||||
wipe(scdCup, _wad);
|
wipe(scdCup, _wad);
|
||||||
free(scdCup, _jam);
|
free(scdCup, _jam);
|
||||||
|
|
||||||
lock(splitCup, _jam);
|
lock(splitCup, _jam);
|
||||||
draw(splitCup, _wad);
|
draw(splitCup, _wad);
|
||||||
|
|
||||||
require(TokenInterface(getSaiAddress()).transfer(getPoolAddress(), _wad), "Not-enough-amt");
|
require(TokenInterface(getSaiAddress()).transfer(getPoolAddress(), _wad), "Not-enough-dai");
|
||||||
PoolInterface(getPoolAddress()).paybackToken(addrArr, false);
|
PoolInterface(getPoolAddress()).paybackToken(addrArr, false);
|
||||||
|
|
||||||
uint finalPoolBal = getPoolAddress().balance;
|
uint finalPoolBal = getPoolAddress().balance;
|
||||||
|
@ -339,6 +406,12 @@ contract MigrateResolver is MCDResolver {
|
||||||
} else {
|
} else {
|
||||||
cdp = migrateToMCD(scdMcdMigration, scdCup, payFeeWith);
|
cdp = migrateToMCD(scdMcdMigration, scdCup, payFeeWith);
|
||||||
}
|
}
|
||||||
|
emit LogMigrate(
|
||||||
|
uint(scdCup),
|
||||||
|
toConvert,
|
||||||
|
payFeeWith,
|
||||||
|
cdp
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user