diff --git a/contracts/connectors/instapool.sol b/contracts/connectors/instapool.sol index 5d04380..712024b 100644 --- a/contracts/connectors/instapool.sol +++ b/contracts/connectors/instapool.sol @@ -1,6 +1,8 @@ pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; +import "../../node_modules/@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; + interface LiqudityInterface { function deposit(address, uint) external payable; function withdraw(address, uint) external; @@ -11,6 +13,8 @@ interface LiqudityInterface { function isTknAllowed(address) external view returns(bool); function tknToCTkn(address) external view returns(address); function liquidityBalance(address, address) external view returns(uint); + + function borrowedToken(address) external view returns(uint); } interface CTokenInterface { @@ -66,6 +70,9 @@ contract DSMath { contract Helpers is DSMath { + + using SafeERC20 for IERC20; + /** * @dev Return ethereum address */ @@ -107,6 +114,12 @@ contract Helpers is DSMath { function connectorID() public pure returns(uint _type, uint _id) { (_type, _id) = (1, 8); } + + function _transfer(address payable to,address token, uint _amt) internal { + token == getAddressETH() ? + to.transfer(_amt) : + IERC20(token).safeTransfer(to, _amt); + } } @@ -214,18 +227,13 @@ contract LiquidityAccess is LiquidityManage { */ function flashPayback(address token, uint getId, uint setId) external payable { LiqudityInterface liquidityContract = LiqudityInterface(getLiquidityAddress()); - uint _amt; + uint _amt = liquidityContract.borrowedToken(token); - if (token == getAddressETH()) { - CETHInterface cethContract = CETHInterface(liquidityContract.tknToCTkn(token)); - _amt = cethContract.borrowBalanceCurrent(address(liquidityContract)); - cethContract.repayBorrowBehalf.value(_amt)(address(liquidityContract)); - } else { - CTokenInterface ctokenContract = CTokenInterface(liquidityContract.tknToCTkn(token)); - _amt = ctokenContract.borrowBalanceCurrent(address(liquidityContract)); - TokenInterface(token).approve(address(ctokenContract), _amt); - require(ctokenContract.repayBorrowBehalf(address(liquidityContract), _amt) == 0, "repay-failed"); - } + address[] memory _tknAddrs = new address[](1); + _tknAddrs[0] = token; + + _transfer(payable(address(liquidityContract)), token, _amt); + liquidityContract.returnLiquidity(_tknAddrs); setUint(setId, _amt); @@ -280,23 +288,9 @@ contract LiquidityAccess is LiquidityManage { uint _length = tokens.length; for (uint i = 0; i < _length; i++) { + uint _amt = liquidityContract.borrowedToken(tokens[i]); - for (uint j = 0; j < _length; j++) { - if (tokens[i] == tokens[j] && i != j) require(false, "tkn-repeated"); - } - - uint _amt; - - if (tokens[i] == getAddressETH()) { - CETHInterface cethContract = CETHInterface(liquidityContract.tknToCTkn(tokens[i])); - _amt = cethContract.borrowBalanceCurrent(address(liquidityContract)); - cethContract.repayBorrowBehalf.value(_amt)(address(liquidityContract)); - } else { - CTokenInterface ctokenContract = CTokenInterface(liquidityContract.tknToCTkn(tokens[i])); - _amt = ctokenContract.borrowBalanceCurrent(address(liquidityContract)); - TokenInterface(tokens[i]).approve(address(ctokenContract), _amt); - require(ctokenContract.repayBorrowBehalf(address(liquidityContract), _amt) == 0, "repay-failed"); - } + _transfer(payable(address(liquidityContract)), tokens[i], _amt); setUint(setId[i], _amt); @@ -306,10 +300,12 @@ contract LiquidityAccess is LiquidityManage { (uint _type, uint _id) = connectorID(); EventInterface(getEventAddr()).emitEvent(_type, _id, _eventCode, _eventParam); } + + liquidityContract.returnLiquidity(tokens); } } contract ConnectInstaPool is LiquidityAccess { - string public name = "InstaPool-v1.1"; + string public name = "InstaPool-v2.1"; } \ No newline at end of file diff --git a/contracts/connectors/makerdao.sol b/contracts/connectors/makerdao.sol index a609821..c9b5437 100644 --- a/contracts/connectors/makerdao.sol +++ b/contracts/connectors/makerdao.sol @@ -184,7 +184,7 @@ contract Helpers is DSMath { * @dev Connector Details */ function connectorID() public pure returns(uint _type, uint _id) { - (_type, _id) = (1, 9); + (_type, _id) = (1, 26); } } @@ -592,7 +592,11 @@ contract BasicResolver is MakerHelpers { address vat = managerContract.vat(); - _amt = _amt == uint(-1) ? _getVaultDebt(vat, ilk, urn) : _amt; + uint _maxDebt = _getVaultDebt(vat, ilk, urn); + + _amt = _amt == uint(-1) ? _maxDebt : _amt; + + require(_maxDebt >= _amt, "paying-excess-debt"); DaiJoinInterface daiJoinContract = DaiJoinInterface(getMcdDaiJoin()); daiJoinContract.dai().approve(getMcdDaiJoin(), _amt); @@ -622,6 +626,7 @@ contract BasicResolver is MakerHelpers { contract BasicExtraResolver is BasicResolver { event LogWithdrawLiquidated(uint256 indexed vault, bytes32 indexed ilk, uint256 tokenAmt, uint256 getId, uint256 setId); + event LogExitDai(uint256 indexed vault, bytes32 indexed ilk, uint256 tokenAmt, uint256 getId, uint256 setId); /** * @dev Withdraw leftover ETH/ERC20_Token after Liquidation. @@ -674,6 +679,53 @@ contract BasicExtraResolver is BasicResolver { EventInterface(getEventAddr()).emitEvent(_type, _id, _eventCode, _eventParam); } + /** + * @dev Exit DAI from urn. + * @param vault Vault ID. + * @param amt token amount to exit. + * @param getId Get token amount at this ID from `InstaMemory` Contract. + * @param setId Set token amount at this ID in `InstaMemory` Contract. + */ + function exitDai( + uint vault, + uint amt, + uint getId, + uint setId + ) external payable { + ManagerLike managerContract = ManagerLike(getMcdManager()); + + uint _amt = getUint(getId, amt); + uint _vault = getVault(managerContract, vault); + (bytes32 ilk, address urn) = getVaultData(managerContract, _vault); + + address daiJoin = getMcdDaiJoin(); + + VatLike vatContract = VatLike(managerContract.vat()); + if(_amt == uint(-1)) { + _amt = vatContract.dai(urn); + _amt = _amt / 10 ** 27; + } + + managerContract.move( + _vault, + address(this), + toRad(_amt) + ); + + if (vatContract.can(address(this), address(daiJoin)) == 0) { + vatContract.hope(daiJoin); + } + + DaiJoinInterface(daiJoin).exit(address(this), _amt); + + setUint(setId, _amt); + + emit LogExitDai(_vault, ilk, _amt, getId, setId); + bytes32 _eventCode = keccak256("LogExitDai(uint256,bytes32,uint256,uint256,uint256)"); + bytes memory _eventParam = abi.encode(_vault, ilk, _amt, getId, setId); + (uint _type, uint _id) = connectorID(); + EventInterface(getEventAddr()).emitEvent(_type, _id, _eventCode, _eventParam); + } } contract DsrResolver is BasicExtraResolver { @@ -771,5 +823,5 @@ contract DsrResolver is BasicExtraResolver { } contract ConnectMaker is DsrResolver { - string public constant name = "MakerDao-v1.1"; + string public constant name = "MakerDao-v1.2"; } \ No newline at end of file