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 {
function allowance(address, address) external view returns (uint);
function balanceOf(address) external view returns (uint);
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 {
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 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 {
@ -38,59 +15,21 @@ interface PepInterface {
interface ComptrollerInterface {
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 getAccountLiquidity(address account) external view returns (uint, uint, uint);
}
interface CTokenInterface {
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 {
function makerToCompound(uint, uint, uint) external returns (uint);
function compoundToMaker(uint, uint, uint) external;
function refillFunds(uint) external;
}
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 {
contract Helper {
/**
* @dev get MakerDAO CDP engine
@ -138,11 +77,6 @@ contract Helper is DSMath {
}
}
}
contract MakerHelper is Helper {
/**
* @dev transfer CDP ownership
*/
@ -150,11 +84,9 @@ contract MakerHelper is Helper {
TubInterface(getSaiTubAddress()).give(bytes32(cdpNum), nextOwner);
}
}
contract CompoundHelper is MakerHelper {
/**
* @dev enter compound market
*/
function enterMarket(address cErc20) internal {
ComptrollerInterface troller = ComptrollerInterface(getComptrollerAddress());
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 {
enterMarket(getCETHAddress());
@ -185,6 +117,9 @@ contract CompoundHelper is MakerHelper {
contract Bridge is CompoundHelper {
/**
* @dev MakerDAO to Compound
*/
function makerToCompound(uint cdpId, uint ethCol, uint daiDebt) public {
give(cdpId, getBridgeAddress());
BridgeInterface bridge = BridgeInterface(getBridgeAddress());
@ -192,10 +127,13 @@ contract Bridge is CompoundHelper {
if (daiDebt > 0) {
borrowDAI(daiAmt);
setApproval(getDaiAddress(), daiAmt, getBridgeAddress());
bridge.takeDebtBack(daiAmt);
bridge.refillFunds(daiAmt);
}
}
/**
* @dev Compound to MakerDAO
*/
function compoundToMaker(uint cdpId, uint ethCol, uint daiDebt) public {
if (cdpId != 0) {
give(cdpId, getBridgeAddress());

View File

@ -77,17 +77,6 @@ contract 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
*/
@ -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 daiAddr = 0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359;
address public registryAddr = 0x498b3BfaBE9F73db90D252bCD4Fa9548Cd0Fd981;
address public registry = 0x498b3BfaBE9F73db90D252bCD4Fa9548Cd0Fd981;
address public sai = 0x448a5065aeBB8E423F0896E6c5D525C040f59af3;
address public ume = 0x448a5065aeBB8E423F0896E6c5D525C040f59af3; // Uniswap Maker Exchange
address public ude = 0x448a5065aeBB8E423F0896E6c5D525C040f59af3; // Uniswap DAI Exchange
address public cEth = 0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5;
address public cDai = 0xF5DCe57282A584D2746FaF1593d3121Fcac444dC;
mapping (address => uint) public deposited; // amount of CToken deposited
/**
* @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
* @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 LogGive(uint cdpNum, address owner, address nextOwner);
@ -321,67 +373,32 @@ contract MakerResolver is Helper {
}
contract CompoundResolver 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);
contract BridgeResolver is MakerResolver {
/**
* @dev Deposit ETH/ERC20 and mint Compound Tokens
* @dev initiated from user wallet to reimburse temporary DAI debt
*/
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
);
}
function refillFunds(uint daiDebt) external {
require(ERC20Interface(daiAddr).transferFrom(msg.sender, address(this),daiDebt), "Contract Approved?");
mintCDAI(daiDebt);
}
/**
* @dev Deposit ETH/ERC20 and mint Compound Tokens
* @dev paying back users debt
*/
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
);
}
}
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?");
function payUserDebt(uint daiDebt) internal {
if (daiDebt > 0) {
redeemUnderlying(cDai, daiDebt);
require(CDAIInterface(cDai).repayBorrowBehalf(msg.sender, daiDebt) == 0, "Enough DAI?");
}
}
}
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
@ -391,24 +408,24 @@ contract BridgeBasics is CompoundResolver {
CTokenInterface cToken = CTokenInterface(cDai);
assert(cToken.mint(amt) == 0);
uint cDaiAmt = wdiv(amt, cToken.exchangeRateCurrent());
deposited[msg.sender] += cDaiAmt;
deposits[msg.sender] += cDaiAmt;
}
/**
* @dev Withdraw DAI from liquidity
*/
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);
uint withdrawAmt = wdiv(amt, cToken.exchangeRateCurrent());
uint daiAmt = amt;
if (withdrawAmt > deposited[msg.sender]) {
withdrawAmt = deposited[msg.sender];
if (withdrawAmt > deposits[msg.sender]) {
withdrawAmt = deposits[msg.sender];
daiAmt = wmul(withdrawAmt, cToken.exchangeRateCurrent());
}
require(cToken.redeem(withdrawAmt) == 0, "something went wrong");
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 {
CTokenInterface cToken = CTokenInterface(cDai);
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
*/
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);
uint withdrawAmt = amt;
if (withdrawAmt > deposited[msg.sender]) {
withdrawAmt = deposited[msg.sender];
if (withdrawAmt > deposits[msg.sender]) {
withdrawAmt = deposits[msg.sender];
}
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) {
redeemUnderlying(cDai, daiDebt);
require(CDAIInterface(cDai).repayBorrowBehalf(msg.sender, daiDebt) == 0, "Enough DAI?");
}
}
function takeDebtBack(uint daiDebt) external {
require(ERC20Interface(daiAddr).transferFrom(msg.sender, address(this),daiDebt), "Contract Approved?");
mintCDAI(daiDebt);
/**
* FOR SECURITY PURPOSE
* checks if only InstaDApp contract wallets can access the bridge
*/
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 MakerDAO to Compound
*/
function makerToCompound(uint cdpId, uint ethCol, uint daiDebt) public payable isUserWallet returns (uint daiAmt) {
daiAmt = wipeAndFree(cdpId, ethCol, daiDebt);
mintCETH(ethCol);
give(cdpId, msg.sender);
}
/**
* @dev Compound to MakerDAO
*/
function compoundToMaker(uint cdpId, uint ethCol, uint daiDebt) public payable isUserWallet {
payUsersDebt(daiDebt);
takeCETH(ethCol);
payUserDebt(daiDebt);
fetchCETH(ethCol);
redeemUnderlying(cEth, ethCol);
uint cdpNum = cdpId > 0 ? cdpId : open();
lockAndDraw(cdpNum, ethCol, daiDebt);
@ -467,11 +490,6 @@ contract Bridge is BridgeBasics {
give(cdpNum, msg.sender);
}
function payUsersDebt(uint daiDebt) internal {
redeemUnderlying(cDai, daiDebt);
require(CDAIInterface(cDai).repayBorrowBehalf(msg.sender, daiDebt) == 0, "Enough DAI?");
}
}