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,
|
||||
address tokenAddr
|
||||
) 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 {
|
||||
|
@ -58,6 +63,16 @@ interface PoolInterface {
|
|||
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 {
|
||||
|
||||
|
@ -112,6 +127,20 @@ contract Helpers is DSMath {
|
|||
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
|
||||
*/
|
||||
|
@ -126,6 +155,13 @@ contract Helpers is DSMath {
|
|||
ude = 0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev get uniswap factory
|
||||
*/
|
||||
function getUniswapFactory() public pure returns (address addr) {
|
||||
addr = 0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
cup = bytes32(cdpNum);
|
||||
function setApproval(address erc20, uint srcAmt, address to) internal {
|
||||
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();
|
||||
}
|
||||
|
||||
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) {
|
||||
address tubAddr = getSaiTubAddress();
|
||||
|
||||
|
@ -160,7 +234,7 @@ contract SCDResolver is Helpers {
|
|||
(address lad,,,) = tub.cups(cup);
|
||||
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());
|
||||
ink = rmul(ink, tub.per()) <= jam ? ink : ink - 1;
|
||||
|
@ -173,73 +247,13 @@ contract SCDResolver is Helpers {
|
|||
}
|
||||
}
|
||||
|
||||
function free(bytes32 cup, uint jam) public {
|
||||
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 {
|
||||
function draw(bytes32 cup, uint _wad) internal {
|
||||
if (_wad > 0) {
|
||||
TubInterface tub = TubInterface(getSaiTubAddress());
|
||||
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 {
|
||||
if (_token.allowance(address(this), _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(
|
||||
address payable scdMcdMigration, // Migration contract address
|
||||
uint wad // Amount to swap
|
||||
|
@ -268,7 +328,6 @@ contract MCDResolver is SCDResolver {
|
|||
address payable scdMcdMigration, // Migration contract address
|
||||
bytes32 cup, // SCD CDP Id to migrate
|
||||
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)
|
||||
{
|
||||
TubInterface tub = TubInterface(getSaiTubAddress());
|
||||
|
@ -281,10 +340,8 @@ contract MCDResolver is SCDResolver {
|
|||
uint govFee = wdiv(tub.rap(cup), uint(val));
|
||||
|
||||
if (payGem != address(0)) {
|
||||
// Swap ETH to WETH => WETH TO MKR
|
||||
|
||||
swapToMkrOtc(payGem, govFee);
|
||||
} 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().transfer(address(scdMcdMigration), govFee), "transfer-failed");
|
||||
|
@ -296,6 +353,7 @@ contract MCDResolver is SCDResolver {
|
|||
|
||||
|
||||
contract MigrateResolver is MCDResolver {
|
||||
event LogMigrate(uint scdCdp, uint toConvert, address payFeeWith, uint mcdCdp);
|
||||
function migrate(
|
||||
bytes32 scdCup,
|
||||
// uint mcdCDP, for merge
|
||||
|
@ -307,13 +365,14 @@ contract MigrateResolver is MCDResolver {
|
|||
TubInterface tub = TubInterface(getSaiTubAddress());
|
||||
uint _jam = rmul(tub.ink(scdCup), tub.per());
|
||||
uint _wad = tub.tab(scdCup);
|
||||
if (toConvert >= 10**18) {
|
||||
if (toConvert < 10**18) {
|
||||
uint initialPoolBal = sub(getPoolAddress().balance, 10000000000);
|
||||
bytes32 splitCup = TubInterface(getSaiTubAddress()).open();
|
||||
|
||||
_jam = wmul(_jam, toConvert);
|
||||
_wad = wmul(_wad, toConvert);
|
||||
|
||||
|
||||
uint[] memory _wadArr = new uint[](1);
|
||||
_wadArr[0] = _wad;
|
||||
|
||||
|
@ -323,13 +382,21 @@ contract MigrateResolver is MCDResolver {
|
|||
// Get liquidity assets to payback user wallet borrowed assets
|
||||
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);
|
||||
free(scdCup, _jam);
|
||||
|
||||
lock(splitCup, _jam);
|
||||
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);
|
||||
|
||||
uint finalPoolBal = getPoolAddress().balance;
|
||||
|
@ -339,6 +406,12 @@ contract MigrateResolver is MCDResolver {
|
|||
} else {
|
||||
cdp = migrateToMCD(scdMcdMigration, scdCup, payFeeWith);
|
||||
}
|
||||
emit LogMigrate(
|
||||
uint(scdCup),
|
||||
toConvert,
|
||||
payFeeWith,
|
||||
cdp
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user