TODOs in receiver

This commit is contained in:
Mubaris NK 2021-04-12 11:32:42 +05:30
parent bd3ebe6ea1
commit 10dde58404
No known key found for this signature in database
GPG Key ID: 9AC09AD0F8D68561
6 changed files with 102 additions and 42 deletions

View File

@ -13,4 +13,28 @@ contract Events {
address[] tokens, address[] tokens,
uint[] amts uint[] amts
); );
event LogUpdateSafeRatioGap(
uint256 oldSafeRatioGap,
uint256 newSafeRatioGap
);
event LogAddSupportedTokens(
uint256[] tokens
);
event LogSettle();
event LogAaveV2Migrate(
address indexed user,
address[] supplyTokens,
address[] borrowTokens,
uint256[] supplyAmts,
uint256[] borrowAmts
);
event LogStateSync(
uint256 indexed stateId,
bytes data
);
} }

View File

@ -10,7 +10,8 @@ import {
TokenMappingInterface, TokenMappingInterface,
AaveData, AaveData,
AaveDataProviderInterface, AaveDataProviderInterface,
AaveInterface AaveInterface,
AccountInterface
} from "./interfaces.sol"; } from "./interfaces.sol";
abstract contract Helpers is Stores, DSMath, Variables { abstract contract Helpers is Stores, DSMath, Variables {
@ -29,21 +30,24 @@ abstract contract Helpers is Stores, DSMath, Variables {
} }
function isPositionSafe() internal returns (bool isOk) { function isPositionSafe() internal returns (bool isOk) {
// TODO: Check the final position health AaveInterface aave = AaveInterface(aaveProvider.getLendingPool());
(,,,,,uint healthFactor) = aave.getUserAccountData(address(this));
uint minLimit = wdiv(1e18, safeRatioGap);
isOk = healthFactor > minLimit;
require(isOk, "position-at-risk"); require(isOk, "position-at-risk");
} }
function transferAtokens(AaveInterface aave, address dsa, address[] memory supplyTokens, uint[] memory supplyAmts) internal { function transferAtokens(AaveInterface aave, address dsa, address[] memory supplyTokens, uint[] memory supplyAmts) internal {
for (uint i = 0; i < supplyTokens.length; i++) { for (uint i = 0; i < supplyTokens.length; i++) {
address _token = supplyTokens[i]; address _token = supplyTokens[i] == maticAddr ? wmaticAddr : supplyTokens[i];
IERC20 _atokenContract = IERC20(_token); // TODO: Fetch atoken from Aave mapping (change _token to atoken address) (address _aToken, ,) = aaveData.getReserveTokensAddresses(_token);
IERC20 _atokenContract = IERC20(_aToken);
uint _atokenBal = _atokenContract.balanceOf(address(this)); uint _atokenBal = _atokenContract.balanceOf(address(this));
uint _supplyAmt = supplyAmts[i]; uint _supplyAmt = supplyAmts[i];
bool isFlash; bool isFlash;
uint _flashAmt; uint _flashAmt;
// get Aave liquidity of token (uint tokenLiq,,,,,,,,,) = aaveData.getReserveData(_token);
uint tokenLiq = uint(0);
if (_atokenBal < _supplyAmt) { if (_atokenBal < _supplyAmt) {
uint _reqAmt = _supplyAmt - _atokenBal; uint _reqAmt = _supplyAmt - _atokenBal;
@ -61,11 +65,11 @@ abstract contract Helpers is Stores, DSMath, Variables {
uint finalSplit = _reqAmt - (splitAmt * (num - 1)); // TODO: to resolve upper decimal error uint finalSplit = _reqAmt - (splitAmt * (num - 1)); // TODO: to resolve upper decimal error
for (uint j = 0; j < num; j++) { for (uint j = 0; j < num; j++) {
if (i < num - 1) { if (j < num - 1) {
aave.borrow(_token, splitAmt, 2, 3288, address(this)); // TODO: is "2" for interest rate mode. Right? aave.borrow(_token, splitAmt, 2, 3288, address(this));
aave.deposit(_token, splitAmt, address(this), 3288); aave.deposit(_token, splitAmt, address(this), 3288);
} else { } else {
aave.borrow(_token, finalSplit, 2, 3288, address(this)); // TODO: is "2" for interest rate mode. Right? aave.borrow(_token, finalSplit, 2, 3288, address(this));
aave.deposit(_token, finalSplit, address(this), 3288); aave.deposit(_token, finalSplit, address(this), 3288);
} }
} }
@ -81,10 +85,9 @@ abstract contract Helpers is Stores, DSMath, Variables {
function borrowAndTransferSpells(AaveInterface aave, address dsa, address[] memory borrowTokens, uint[] memory borrowAmts) internal { function borrowAndTransferSpells(AaveInterface aave, address dsa, address[] memory borrowTokens, uint[] memory borrowAmts) internal {
for (uint i = 0; i < borrowTokens.length; i++) { for (uint i = 0; i < borrowTokens.length; i++) {
address _token = borrowTokens[i]; address _token = supplyTokens[i] == maticAddr ? wmaticAddr : supplyTokens[i];
address _atoken = address(0); // TODO: Fetch atoken address (address _atoken, ,) = aaveData.getReserveTokensAddresses(_token);
// get Aave liquidity of token (uint tokenLiq,,,,,,,,,) = aaveData.getReserveData(_token);
uint tokenLiq = uint(0);
uint _borrowAmt = borrowAmts[i]; uint _borrowAmt = borrowAmts[i];
uint _flashAmt; uint _flashAmt;
@ -106,16 +109,16 @@ abstract contract Helpers is Stores, DSMath, Variables {
for (uint j = 0; j < num; j++) { for (uint j = 0; j < num; j++) {
targets[j] = "AAVE-A"; targets[j] = "AAVE-A";
uint k = j * 2; uint k = j * 2;
if (i < num - 1) { if (j < num - 1) {
// borrow spell // borrow spell
castData[k] = abi.encode("6abcd3de", _token, splitAmt, 2, 0, 0); // TODO: verify this & is rate mode right? castData[k] = abi.encode("6abcd3de", _token, splitAmt, 2, 0, 0);
// deposit spell // deposit spell
castData[k+1] = abi.encode("ce88b439", _token, splitAmt, 2, 0, 0); // TODO: verify this & is rate mode right? castData[k+1] = abi.encode("ce88b439", _token, splitAmt, 2, 0, 0);
} else { } else {
// borrow spell // borrow spell
castData[k] = abi.encode("6abcd3de", _token, finalSplit, 2, 0, 0); // TODO: verify this & is rate mode right? castData[k] = abi.encode("6abcd3de", _token, finalSplit, 2, 0, 0);
// deposit spell // deposit spell
castData[k+1] = abi.encode("ce88b439", _token, finalSplit, 2, 0, 0); // TODO: verify this & is rate mode right? castData[k+1] = abi.encode("ce88b439", _token, finalSplit, 2, 0, 0);
} }
} }
@ -125,7 +128,8 @@ abstract contract Helpers is Stores, DSMath, Variables {
targets[spellsAmt] = "BASIC-A"; // TODO: right spell? targets[spellsAmt] = "BASIC-A"; // TODO: right spell?
castData[spellsAmt] = abi.encode("4bd3ab82", _atoken, _borrowAmt, address(this), 0, 0); // encode the data of atoken withdrawal castData[spellsAmt] = abi.encode("4bd3ab82", _atoken, _borrowAmt, address(this), 0, 0); // encode the data of atoken withdrawal
// TODO: Call DSAs cast and borrow (maybe create a new implementation which only this contract can run?)
AccountInterface(dsa).castMigrate(targets, castData, address(this));
} }
} }

View File

@ -5,12 +5,11 @@ interface AccountInterface {
function enable(address) external; function enable(address) external;
function disable(address) external; function disable(address) external;
function isAuth(address) external view returns (bool); function isAuth(address) external view returns (bool);
function cast( function castMigrate(
string[] calldata _targets, string[] calldata _targets,
bytes[] calldata _datas, bytes[] calldata _datas,
address _origin address _origin
) external payable returns (bytes32); ) external payable returns (bytes32);
function migrateAave(address) external payable returns (bytes32);
} }
interface TokenMappingInterface { interface TokenMappingInterface {
@ -62,6 +61,18 @@ interface AaveDataProviderInterface {
bool isActive, bool isActive,
bool isFrozen bool isFrozen
); );
function getReserveData(address asset) external view returns (
uint256 availableLiquidity,
uint256 totalStableDebt,
uint256 totalVariableDebt,
uint256 liquidityRate,
uint256 variableBorrowRate,
uint256 stableBorrowRate,
uint256 averageStableBorrowRate,
uint256 liquidityIndex,
uint256 variableBorrowIndex,
uint40 lastUpdateTimestamp
);
} }
interface AaveInterface { interface AaveInterface {

View File

@ -11,6 +11,22 @@ import { Helpers } from "./helpers.sol";
contract MigrateResolver is Helpers, Events { contract MigrateResolver is Helpers, Events {
using SafeERC20 for IERC20; using SafeERC20 for IERC20;
function updateSafeRatioGap(uint _safeRatioGap) public {
require(msg.sender == instaIndex.master(), "not-master");
emit LogUpdateSafeRatioGap(safeRatioGap, _safeRatioGap);
safeRatioGap = _safeRatioGap;
}
function addTokenSupport(address[] memory _tokens) public {
require(msg.sender == instaIndex.master(), "not-master");
for (uint i = 0; i < _tokens.length; i++) {
require(!isSupportedToken[_tokens[i]], "already-added");
isSupportedToken[_tokens[i]] = true;
supportedTokens.push(_tokens[i]);
}
emit LogAddSupportedTokens(_tokens);
}
function spell(address _target, bytes memory _data) external { function spell(address _target, bytes memory _data) external {
require(msg.sender == instaIndex.master(), "not-master"); require(msg.sender == instaIndex.master(), "not-master");
require(_target != address(0), "target-invalid"); require(_target != address(0), "target-invalid");
@ -39,19 +55,23 @@ contract MigrateResolver is Helpers, Events {
for (uint256 i = 0; i < _length; i++) { for (uint256 i = 0; i < _length; i++) {
require(isSupportedToken[tokens[i]], "token-not-enabled"); require(isSupportedToken[tokens[i]], "token-not-enabled");
uint _amt; uint _amt;
address _token = tokens[i]; bool isMatic = tokens[i] == maticAddr;
if (_token == maticAddr) { address _token = isMatic ? wmaticAddr : tokens[i];
IERC20 tokenContract = IERC20(_token);
if (isMatic) {
require(msg.value == amts[i]); require(msg.value == amts[i]);
_amt = msg.value;
TokenInterface(wmaticAddr).deposit{value: msg.value}(); TokenInterface(wmaticAddr).deposit{value: msg.value}();
aave.deposit(wmaticAddr, _amt, address(this), 3288); _amt = msg.value;
} else { } else {
IERC20 tokenContract = IERC20(_token);
_amt = amts[i] == uint(-1) ? tokenContract.balanceOf(msg.sender) : amts[i]; _amt = amts[i] == uint(-1) ? tokenContract.balanceOf(msg.sender) : amts[i];
tokenContract.safeTransferFrom(msg.sender, address(this), _amt); tokenContract.safeTransferFrom(msg.sender, address(this), _amt);
aave.deposit(_token, _amt, address(this), 3288);
} }
tokenContract.safeApprove(address(aave),_amt);
aave.deposit(_token, _amt, address(this), 3288);
_amts[i] = _amt; _amts[i] = _amt;
deposits[msg.sender][_token] += _amt; deposits[msg.sender][_token] += _amt;
@ -71,7 +91,8 @@ contract MigrateResolver is Helpers, Events {
for (uint256 i = 0; i < _length; i++) { for (uint256 i = 0; i < _length; i++) {
require(isSupportedToken[tokens[i]], "token-not-enabled"); require(isSupportedToken[tokens[i]], "token-not-enabled");
uint _amt = amts[i]; uint _amt = amts[i];
address _token = tokens[i]; bool isMatic = tokens[i] == maticAddr;
address _token = isMatic ? wmaticAddr : tokens[i];
uint maxAmt = deposits[msg.sender][_token]; uint maxAmt = deposits[msg.sender][_token];
if (_amt > maxAmt) { if (_amt > maxAmt) {
@ -80,14 +101,20 @@ contract MigrateResolver is Helpers, Events {
deposits[msg.sender][_token] = sub(maxAmt, _amt); deposits[msg.sender][_token] = sub(maxAmt, _amt);
if (_token == maticAddr) { if (isMatic) {
TokenInterface _tokenContract = TokenInterface(wmaticAddr); TokenInterface _tokenContract = TokenInterface(wmaticAddr);
uint _maticBal = address(this).balance; uint _maticBal = address(this).balance;
uint _tknBal = _tokenContract.balanceOf(address(this)); uint _tknBal = _tokenContract.balanceOf(address(this));
if ((_maticBal + _tknBal) < _amt) { if (_maticBal > _amt) {
aave.withdraw(wmaticAddr, sub(_amt, (_tknBal + _maticBal)), address(this)); msg.sender.call{value: _amt}("");
_amts[i] = _amt;
continue;
} }
_tokenContract.withdraw((sub(_amt, _maticBal)));
if ((_ethBal + _tknBal) < _amt) {
aave.withdraw(wmaticAddr, sub(_amt, (_tknBal + _ethBal)), address(this));
}
_tokenContract.withdraw((sub(_amt, _ethBal)));
msg.sender.call{value: _amt}(""); msg.sender.call{value: _amt}("");
} else { } else {
IERC20 _tokenContract = IERC20(_token); IERC20 _tokenContract = IERC20(_token);
@ -139,7 +166,7 @@ contract MigrateResolver is Helpers, Events {
} }
} }
} }
// TODO: emit event emit LogSettle();
} }
} }
@ -167,7 +194,7 @@ contract AaveV2Migrator is MigrateResolver {
isPositionSafe(); isPositionSafe();
// TODO: emit event emit LogAaveV2Migrate(dsa, supplyTokens, borrowTokens, supplyAmts, supplyAmts);
} }
function onStateReceive(uint256 stateId, bytes calldata receivedData) external { function onStateReceive(uint256 stateId, bytes calldata receivedData) external {
@ -178,7 +205,7 @@ contract AaveV2Migrator is MigrateResolver {
// Can't do it via any address as user can migrate 2 times // Can't do it via any address as user can migrate 2 times
positions[stateId] = receivedData; positions[stateId] = receivedData;
// TODO: add event emit LogStateSync(stateId, receivedData);
} }
function migrate(uint _id) external { function migrate(uint _id) external {
@ -191,7 +218,5 @@ contract AaveV2Migrator is MigrateResolver {
_migratePosition(data); _migratePosition(data);
delete positions[_id]; delete positions[_id];
// TODO: add event
} }
} }

View File

@ -10,7 +10,6 @@ import {
contract Variables { contract Variables {
// This will be used to have debt/collateral ratio always 20% less than liquidation // This will be used to have debt/collateral ratio always 20% less than liquidation
// TODO: Is this number correct for it?
uint public safeRatioGap = 200000000000000000; // 20%? 2e17 uint public safeRatioGap = 200000000000000000; // 20%? 2e17
// TODO: Add function for flash deposits and withdraw // TODO: Add function for flash deposits and withdraw
@ -25,8 +24,7 @@ contract Variables {
/** /**
* @dev Aave Data Provider * @dev Aave Data Provider
*/ */
// TODO: add L2 Data provider address AaveDataProviderInterface constant internal aaveData = AaveDataProviderInterface(0x7551b5D2763519d4e37e8B81929D336De671d46d);
AaveDataProviderInterface constant internal aaveData = AaveDataProviderInterface(address(0));
// dsa => position // dsa => position

View File

@ -11,8 +11,6 @@ import { Events } from "./events.sol";
contract LiquidityResolver is Helpers, Events { contract LiquidityResolver is Helpers, Events {
using SafeERC20 for IERC20; using SafeERC20 for IERC20;
event variablesUpdate(uint _safeRatioGap, uint _fee);
function updateVariables(uint _safeRatioGap, uint _fee) public { function updateVariables(uint _safeRatioGap, uint _fee) public {
require(msg.sender == instaIndex.master(), "not-master"); require(msg.sender == instaIndex.master(), "not-master");
emit LogUpdateVariables(fee, _fee, safeRatioGap, _safeRatioGap); emit LogUpdateVariables(fee, _fee, safeRatioGap, _safeRatioGap);