Beautified bridge contarcts code.

This commit is contained in:
Sowmayjain 2019-06-20 19:11:02 +05:30
parent b1f0a79ddd
commit 15b2009965
3 changed files with 128 additions and 172 deletions

View File

@ -2,34 +2,11 @@ pragma solidity ^0.5.7;
interface ERC20Interface { interface ERC20Interface {
function allowance(address, address) external view returns (uint); function allowance(address, address) external view returns (uint);
function balanceOf(address) external view returns (uint);
function approve(address, uint) external; function approve(address, uint) external;
function transfer(address, uint) external returns (bool);
function transferFrom(address, address, uint) external returns (bool);
function deposit() external payable;
function withdraw(uint) external;
} }
interface TubInterface { interface TubInterface {
function open() external returns (bytes32);
function join(uint) external;
function exit(uint) external;
function lock(bytes32, uint) external;
function free(bytes32, uint) external;
function draw(bytes32, uint) external;
function wipe(bytes32, uint) external;
function give(bytes32, address) external; function give(bytes32, address) external;
function shut(bytes32) external;
function cups(bytes32) external view returns (address, uint, uint, uint);
function gem() external view returns (ERC20Interface);
function gov() external view returns (ERC20Interface);
function skr() external view returns (ERC20Interface);
function sai() external view returns (ERC20Interface);
function ink(bytes32) external view returns (uint);
function tab(bytes32) external returns (uint);
function rap(bytes32) external returns (uint);
function per() external view returns (uint);
function pep() external view returns (PepInterface);
} }
interface PepInterface { interface PepInterface {
@ -38,59 +15,21 @@ interface PepInterface {
interface ComptrollerInterface { interface ComptrollerInterface {
function enterMarkets(address[] calldata cTokens) external returns (uint[] memory); function enterMarkets(address[] calldata cTokens) external returns (uint[] memory);
function exitMarket(address cTokenAddress) external returns (uint);
function getAssetsIn(address account) external view returns (address[] memory); function getAssetsIn(address account) external view returns (address[] memory);
function getAccountLiquidity(address account) external view returns (uint, uint, uint);
} }
interface CTokenInterface { interface CTokenInterface {
function borrow(uint borrowAmount) external returns (uint); function borrow(uint borrowAmount) external returns (uint);
function exchangeRateCurrent() external returns (uint);
function transfer(address, uint) external returns (bool);
function transferFrom(address, address, uint) external returns (bool);
} }
interface BridgeInterface { interface BridgeInterface {
function makerToCompound(uint, uint, uint) external returns (uint); function makerToCompound(uint, uint, uint) external returns (uint);
function compoundToMaker(uint, uint, uint) external; function compoundToMaker(uint, uint, uint) external;
function refillFunds(uint) external;
} }
contract Helper {
contract DSMath {
function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x, "math-not-safe");
}
function mul(uint x, uint y) internal pure returns (uint z) {
require(y == 0 || (z = x * y) / y == x, "math-not-safe");
}
uint constant WAD = 10 ** 18;
uint constant RAY = 10 ** 27;
function rmul(uint x, uint y) internal pure returns (uint z) {
z = add(mul(x, y), RAY / 2) / RAY;
}
function rdiv(uint x, uint y) internal pure returns (uint z) {
z = add(mul(x, RAY), y / 2) / y;
}
function wmul(uint x, uint y) internal pure returns (uint z) {
z = add(mul(x, y), WAD / 2) / WAD;
}
function wdiv(uint x, uint y) internal pure returns (uint z) {
z = add(mul(x, WAD), y / 2) / y;
}
}
contract Helper is DSMath {
/** /**
* @dev get MakerDAO CDP engine * @dev get MakerDAO CDP engine
@ -138,11 +77,6 @@ contract Helper is DSMath {
} }
} }
}
contract MakerHelper is Helper {
/** /**
* @dev transfer CDP ownership * @dev transfer CDP ownership
*/ */
@ -150,11 +84,9 @@ contract MakerHelper is Helper {
TubInterface(getSaiTubAddress()).give(bytes32(cdpNum), nextOwner); TubInterface(getSaiTubAddress()).give(bytes32(cdpNum), nextOwner);
} }
} /**
* @dev enter compound market
*/
contract CompoundHelper is MakerHelper {
function enterMarket(address cErc20) internal { function enterMarket(address cErc20) internal {
ComptrollerInterface troller = ComptrollerInterface(getComptrollerAddress()); ComptrollerInterface troller = ComptrollerInterface(getComptrollerAddress());
address[] memory markets = troller.getAssetsIn(address(this)); address[] memory markets = troller.getAssetsIn(address(this));
@ -172,7 +104,7 @@ contract CompoundHelper is MakerHelper {
} }
/** /**
* @dev borrow ETH/ERC20 * @dev borrow DAI from compound
*/ */
function borrowDAI(uint tokenAmt) internal { function borrowDAI(uint tokenAmt) internal {
enterMarket(getCETHAddress()); enterMarket(getCETHAddress());
@ -185,6 +117,9 @@ contract CompoundHelper is MakerHelper {
contract Bridge is CompoundHelper { contract Bridge is CompoundHelper {
/**
* @dev MakerDAO to Compound
*/
function makerToCompound(uint cdpId, uint ethCol, uint daiDebt) public { function makerToCompound(uint cdpId, uint ethCol, uint daiDebt) public {
give(cdpId, getBridgeAddress()); give(cdpId, getBridgeAddress());
BridgeInterface bridge = BridgeInterface(getBridgeAddress()); BridgeInterface bridge = BridgeInterface(getBridgeAddress());
@ -192,10 +127,13 @@ contract Bridge is CompoundHelper {
if (daiDebt > 0) { if (daiDebt > 0) {
borrowDAI(daiAmt); borrowDAI(daiAmt);
setApproval(getDaiAddress(), daiAmt, getBridgeAddress()); setApproval(getDaiAddress(), daiAmt, getBridgeAddress());
bridge.takeDebtBack(daiAmt); bridge.refillFunds(daiAmt);
} }
} }
/**
* @dev Compound to MakerDAO
*/
function compoundToMaker(uint cdpId, uint ethCol, uint daiDebt) public { function compoundToMaker(uint cdpId, uint ethCol, uint daiDebt) public {
if (cdpId != 0) { if (cdpId != 0) {
give(cdpId, getBridgeAddress()); give(cdpId, getBridgeAddress());

View File

@ -77,17 +77,6 @@ contract DSMath {
contract Helpers is DSMath { contract Helpers is DSMath {
/**
* @dev setting allowance to compound for the "user proxy" if required
*/
function setApproval(address erc20, uint srcAmt, address to) internal {
ERC20Interface erc20Contract = ERC20Interface(erc20);
uint tokenAllowance = erc20Contract.allowance(address(this), to);
if (srcAmt > tokenAllowance) {
erc20Contract.approve(to, 2**255);
}
}
/** /**
* @dev get ethereum address for trade * @dev get ethereum address for trade
*/ */
@ -135,6 +124,17 @@ contract Helpers is DSMath {
} }
} }
/**
* @dev setting allowance to compound for the "user proxy" if required
*/
function setApproval(address erc20, uint srcAmt, address to) internal {
ERC20Interface erc20Contract = ERC20Interface(erc20);
uint tokenAllowance = erc20Contract.allowance(address(this), to);
if (srcAmt > tokenAllowance) {
erc20Contract.approve(to, 2**255);
}
}
} }

View File

@ -113,13 +113,12 @@ contract Helper is DSMath {
address public ethAddr = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; address public ethAddr = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
address public daiAddr = 0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359; address public daiAddr = 0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359;
address public registryAddr = 0x498b3BfaBE9F73db90D252bCD4Fa9548Cd0Fd981; address public registry = 0x498b3BfaBE9F73db90D252bCD4Fa9548Cd0Fd981;
address public sai = 0x448a5065aeBB8E423F0896E6c5D525C040f59af3; address public sai = 0x448a5065aeBB8E423F0896E6c5D525C040f59af3;
address public ume = 0x448a5065aeBB8E423F0896E6c5D525C040f59af3; // Uniswap Maker Exchange address public ume = 0x448a5065aeBB8E423F0896E6c5D525C040f59af3; // Uniswap Maker Exchange
address public ude = 0x448a5065aeBB8E423F0896E6c5D525C040f59af3; // Uniswap DAI Exchange address public ude = 0x448a5065aeBB8E423F0896E6c5D525C040f59af3; // Uniswap DAI Exchange
address public cEth = 0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5; address public cEth = 0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5;
address public cDai = 0xF5DCe57282A584D2746FaF1593d3121Fcac444dC; address public cDai = 0xF5DCe57282A584D2746FaF1593d3121Fcac444dC;
mapping (address => uint) public deposited; // amount of CToken deposited
/** /**
* @dev setting allowance to compound for the "user proxy" if required * @dev setting allowance to compound for the "user proxy" if required
@ -138,14 +137,6 @@ contract Helper is DSMath {
} }
} }
modifier isUserWallet {
address userAdd = UserWalletInterface(msg.sender).owner();
address walletAdd = RegistryInterface(registry).proxies(userAdd);
require(walletAdd != address(0), "not-user-wallet");
require(walletAdd == msg.sender, "not-wallet-owner");
_;
}
/** /**
* @dev Redeem ETH/ERC20 and mint Compound Tokens * @dev Redeem ETH/ERC20 and mint Compound Tokens
* @param tokenAmt Amount of token To Redeem * @param tokenAmt Amount of token To Redeem
@ -163,7 +154,68 @@ contract Helper is DSMath {
} }
contract MakerResolver is Helper { contract CompoundResolver is Helper {
event LogMint(address erc20, address cErc20, uint tokenAmt, address owner);
event LogRedeem(address erc20, address cErc20, uint tokenAmt, address owner);
event LogBorrow(address erc20, address cErc20, uint tokenAmt, address owner);
event LogRepay(address erc20, address cErc20, uint tokenAmt, address owner);
/**
* @dev Deposit ETH/ERC20 and mint Compound Tokens
*/
function mintCETH(uint ethAmt) internal {
if (ethAmt > 0) {
CETHInterface cToken = CETHInterface(cEth);
cToken.mint.value(ethAmt)();
uint cEthToReturn = wdiv(ethAmt, CTokenInterface(cEth).exchangeRateCurrent());
cToken.transfer(msg.sender, cEthToReturn);
emit LogMint(
ethAddr,
cEth,
ethAmt,
msg.sender
);
}
}
/**
* @dev Deposit ETH/ERC20 and mint Compound Tokens
*/
function mintCDAI(uint tokenAmt) internal {
if (tokenAmt > 0) {
ERC20Interface token = ERC20Interface(daiAddr);
uint toDeposit = token.balanceOf(msg.sender);
toDeposit = toDeposit > tokenAmt ? tokenAmt : toDeposit;
token.transferFrom(msg.sender, address(this), toDeposit);
CDAIInterface cToken = CDAIInterface(cDai);
assert(cToken.mint(toDeposit) == 0);
emit LogMint(
daiAddr,
cDai,
tokenAmt,
msg.sender
);
}
}
/**
* @dev Deposit ETH/ERC20 and mint Compound Tokens
*/
function fetchCETH(uint ethAmt) internal {
if (ethAmt > 0) {
CTokenInterface cToken = CTokenInterface(cEth);
uint cTokenAmt = wdiv(ethAmt, cToken.exchangeRateCurrent());
uint cEthBal = cToken.balanceOf(msg.sender);
cTokenAmt = cEthBal > cTokenAmt ? cTokenAmt : cTokenAmt - 1;
require(ERC20Interface(cEth).transferFrom(msg.sender, address(this), cTokenAmt), "Contract Approved?");
}
}
}
contract MakerResolver is CompoundResolver {
event LogOpen(uint cdpNum, address owner); event LogOpen(uint cdpNum, address owner);
event LogGive(uint cdpNum, address owner, address nextOwner); event LogGive(uint cdpNum, address owner, address nextOwner);
@ -321,67 +373,32 @@ contract MakerResolver is Helper {
} }
contract CompoundResolver is MakerResolver { contract BridgeResolver is MakerResolver {
event LogMint(address erc20, address cErc20, uint tokenAmt, address owner);
event LogRedeem(address erc20, address cErc20, uint tokenAmt, address owner);
event LogBorrow(address erc20, address cErc20, uint tokenAmt, address owner);
event LogRepay(address erc20, address cErc20, uint tokenAmt, address owner);
/** /**
* @dev Deposit ETH/ERC20 and mint Compound Tokens * @dev initiated from user wallet to reimburse temporary DAI debt
*/ */
function mintCETH(uint ethAmt) internal { function refillFunds(uint daiDebt) external {
if (ethAmt > 0) { require(ERC20Interface(daiAddr).transferFrom(msg.sender, address(this),daiDebt), "Contract Approved?");
CETHInterface cToken = CETHInterface(cEth); mintCDAI(daiDebt);
cToken.mint.value(ethAmt)();
uint cEthToReturn = wdiv(ethAmt, CTokenInterface(cEth).exchangeRateCurrent());
cToken.transfer(msg.sender, cEthToReturn);
emit LogMint(
ethAddr,
cEth,
ethAmt,
msg.sender
);
}
} }
/** /**
* @dev Deposit ETH/ERC20 and mint Compound Tokens * @dev paying back users debt
*/ */
function mintCDAI(uint tokenAmt) internal { function payUserDebt(uint daiDebt) internal {
if (tokenAmt > 0) { if (daiDebt > 0) {
ERC20Interface token = ERC20Interface(daiAddr); redeemUnderlying(cDai, daiDebt);
uint toDeposit = token.balanceOf(msg.sender); require(CDAIInterface(cDai).repayBorrowBehalf(msg.sender, daiDebt) == 0, "Enough DAI?");
toDeposit = toDeposit > tokenAmt ? tokenAmt : toDeposit;
token.transferFrom(msg.sender, address(this), toDeposit);
CDAIInterface cToken = CDAIInterface(cDai);
assert(cToken.mint(toDeposit) == 0);
emit LogMint(
daiAddr,
cDai,
tokenAmt,
msg.sender
);
}
}
function takeCETH(uint ethAmt) internal {
if (ethAmt > 0) {
CTokenInterface cToken = CTokenInterface(cEth);
uint cTokenAmt = wdiv(ethAmt, cToken.exchangeRateCurrent());
uint cEthBal = cToken.balanceOf(msg.sender);
cTokenAmt = cEthBal > cTokenAmt ? cTokenAmt : cTokenAmt - 1;
require(ERC20Interface(cEth).transferFrom(msg.sender, address(this), cTokenAmt), "Contract Approved?");
} }
} }
} }
contract BridgeBasics is CompoundResolver { contract LiquidityProvider is BridgeResolver {
mapping (address => uint) public deposited; // amount of CToken deposited mapping (address => uint) public deposits; // amount of CDAI deposits
/** /**
* @dev Deposit DAI for liquidity * @dev Deposit DAI for liquidity
@ -391,24 +408,24 @@ contract BridgeBasics is CompoundResolver {
CTokenInterface cToken = CTokenInterface(cDai); CTokenInterface cToken = CTokenInterface(cDai);
assert(cToken.mint(amt) == 0); assert(cToken.mint(amt) == 0);
uint cDaiAmt = wdiv(amt, cToken.exchangeRateCurrent()); uint cDaiAmt = wdiv(amt, cToken.exchangeRateCurrent());
deposited[msg.sender] += cDaiAmt; deposits[msg.sender] += cDaiAmt;
} }
/** /**
* @dev Withdraw DAI from liquidity * @dev Withdraw DAI from liquidity
*/ */
function withdrawDAI(uint amt) public { function withdrawDAI(uint amt) public {
require(deposited[msg.sender] != 0, "Nothing to Withdraw"); require(deposits[msg.sender] != 0, "Nothing to Withdraw");
CTokenInterface cToken = CTokenInterface(cDai); CTokenInterface cToken = CTokenInterface(cDai);
uint withdrawAmt = wdiv(amt, cToken.exchangeRateCurrent()); uint withdrawAmt = wdiv(amt, cToken.exchangeRateCurrent());
uint daiAmt = amt; uint daiAmt = amt;
if (withdrawAmt > deposited[msg.sender]) { if (withdrawAmt > deposits[msg.sender]) {
withdrawAmt = deposited[msg.sender]; withdrawAmt = deposits[msg.sender];
daiAmt = wmul(withdrawAmt, cToken.exchangeRateCurrent()); daiAmt = wmul(withdrawAmt, cToken.exchangeRateCurrent());
} }
require(cToken.redeem(withdrawAmt) == 0, "something went wrong"); require(cToken.redeem(withdrawAmt) == 0, "something went wrong");
ERC20Interface(daiAddr).transfer(msg.sender, daiAmt); ERC20Interface(daiAddr).transfer(msg.sender, daiAmt);
deposited[msg.sender] -= withdrawAmt; deposits[msg.sender] -= withdrawAmt;
} }
/** /**
@ -417,49 +434,55 @@ contract BridgeBasics is CompoundResolver {
function depositCDAI(uint amt) public { function depositCDAI(uint amt) public {
CTokenInterface cToken = CTokenInterface(cDai); CTokenInterface cToken = CTokenInterface(cDai);
require(cToken.transferFrom(msg.sender, address(this), amt) == true, "Nothing to deposit"); require(cToken.transferFrom(msg.sender, address(this), amt) == true, "Nothing to deposit");
deposited[msg.sender] += amt; deposits[msg.sender] += amt;
} }
/** /**
* @dev Withdraw CDAI from liquidity * @dev Withdraw CDAI from liquidity
*/ */
function withdrawCDAI(uint amt) public { function withdrawCDAI(uint amt) public {
require(deposited[msg.sender] != 0, "Nothing to Withdraw"); require(deposits[msg.sender] != 0, "Nothing to Withdraw");
CTokenInterface cToken = CTokenInterface(cDai); CTokenInterface cToken = CTokenInterface(cDai);
uint withdrawAmt = amt; uint withdrawAmt = amt;
if (withdrawAmt > deposited[msg.sender]) { if (withdrawAmt > deposits[msg.sender]) {
withdrawAmt = deposited[msg.sender]; withdrawAmt = deposits[msg.sender];
} }
cToken.transfer(msg.sender, withdrawAmt); cToken.transfer(msg.sender, withdrawAmt);
deposited[msg.sender] -= withdrawAmt; deposits[msg.sender] -= withdrawAmt;
} }
} }
contract Bridge is BridgeBasics { contract Bridge is LiquidityProvider {
function payUsersDebt(uint daiDebt) internal { /**
if (daiDebt > 0) { * FOR SECURITY PURPOSE
redeemUnderlying(cDai, daiDebt); * checks if only InstaDApp contract wallets can access the bridge
require(CDAIInterface(cDai).repayBorrowBehalf(msg.sender, daiDebt) == 0, "Enough DAI?"); */
} modifier isUserWallet {
} address userAdd = UserWalletInterface(msg.sender).owner();
address walletAdd = RegistryInterface(registry).proxies(userAdd);
function takeDebtBack(uint daiDebt) external { require(walletAdd != address(0), "not-user-wallet");
require(ERC20Interface(daiAddr).transferFrom(msg.sender, address(this),daiDebt), "Contract Approved?"); require(walletAdd == msg.sender, "not-wallet-owner");
mintCDAI(daiDebt); _;
} }
/**
* @dev MakerDAO to Compound
*/
function makerToCompound(uint cdpId, uint ethCol, uint daiDebt) public payable isUserWallet returns (uint daiAmt) { function makerToCompound(uint cdpId, uint ethCol, uint daiDebt) public payable isUserWallet returns (uint daiAmt) {
daiAmt = wipeAndFree(cdpId, ethCol, daiDebt); daiAmt = wipeAndFree(cdpId, ethCol, daiDebt);
mintCETH(ethCol); mintCETH(ethCol);
give(cdpId, msg.sender); give(cdpId, msg.sender);
} }
/**
* @dev Compound to MakerDAO
*/
function compoundToMaker(uint cdpId, uint ethCol, uint daiDebt) public payable isUserWallet { function compoundToMaker(uint cdpId, uint ethCol, uint daiDebt) public payable isUserWallet {
payUsersDebt(daiDebt); payUserDebt(daiDebt);
takeCETH(ethCol); fetchCETH(ethCol);
redeemUnderlying(cEth, ethCol); redeemUnderlying(cEth, ethCol);
uint cdpNum = cdpId > 0 ? cdpId : open(); uint cdpNum = cdpId > 0 ? cdpId : open();
lockAndDraw(cdpNum, ethCol, daiDebt); lockAndDraw(cdpNum, ethCol, daiDebt);
@ -467,11 +490,6 @@ contract Bridge is BridgeBasics {
give(cdpNum, msg.sender); give(cdpNum, msg.sender);
} }
function payUsersDebt(uint daiDebt) internal {
redeemUnderlying(cDai, daiDebt);
require(CDAIInterface(cDai).repayBorrowBehalf(msg.sender, daiDebt) == 0, "Enough DAI?");
}
} }