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,
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,
AaveData,
AaveDataProviderInterface,
AaveInterface
AaveInterface,
AccountInterface
} from "./interfaces.sol";
abstract contract Helpers is Stores, DSMath, Variables {
@ -29,21 +30,24 @@ abstract contract Helpers is Stores, DSMath, Variables {
}
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");
}
function transferAtokens(AaveInterface aave, address dsa, address[] memory supplyTokens, uint[] memory supplyAmts) internal {
for (uint i = 0; i < supplyTokens.length; i++) {
address _token = supplyTokens[i];
IERC20 _atokenContract = IERC20(_token); // TODO: Fetch atoken from Aave mapping (change _token to atoken address)
address _token = supplyTokens[i] == maticAddr ? wmaticAddr : supplyTokens[i];
(address _aToken, ,) = aaveData.getReserveTokensAddresses(_token);
IERC20 _atokenContract = IERC20(_aToken);
uint _atokenBal = _atokenContract.balanceOf(address(this));
uint _supplyAmt = supplyAmts[i];
bool isFlash;
uint _flashAmt;
// get Aave liquidity of token
uint tokenLiq = uint(0);
(uint tokenLiq,,,,,,,,,) = aaveData.getReserveData(_token);
if (_atokenBal < _supplyAmt) {
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
for (uint j = 0; j < num; j++) {
if (i < num - 1) {
aave.borrow(_token, splitAmt, 2, 3288, address(this)); // TODO: is "2" for interest rate mode. Right?
if (j < num - 1) {
aave.borrow(_token, splitAmt, 2, 3288, address(this));
aave.deposit(_token, splitAmt, address(this), 3288);
} 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);
}
}
@ -81,10 +85,9 @@ abstract contract Helpers is Stores, DSMath, Variables {
function borrowAndTransferSpells(AaveInterface aave, address dsa, address[] memory borrowTokens, uint[] memory borrowAmts) internal {
for (uint i = 0; i < borrowTokens.length; i++) {
address _token = borrowTokens[i];
address _atoken = address(0); // TODO: Fetch atoken address
// get Aave liquidity of token
uint tokenLiq = uint(0);
address _token = supplyTokens[i] == maticAddr ? wmaticAddr : supplyTokens[i];
(address _atoken, ,) = aaveData.getReserveTokensAddresses(_token);
(uint tokenLiq,,,,,,,,,) = aaveData.getReserveData(_token);
uint _borrowAmt = borrowAmts[i];
uint _flashAmt;
@ -106,16 +109,16 @@ abstract contract Helpers is Stores, DSMath, Variables {
for (uint j = 0; j < num; j++) {
targets[j] = "AAVE-A";
uint k = j * 2;
if (i < num - 1) {
if (j < num - 1) {
// 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
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 {
// 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
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?
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 disable(address) external;
function isAuth(address) external view returns (bool);
function cast(
function castMigrate(
string[] calldata _targets,
bytes[] calldata _datas,
address _origin
) external payable returns (bytes32);
function migrateAave(address) external payable returns (bytes32);
}
interface TokenMappingInterface {
@ -62,6 +61,18 @@ interface AaveDataProviderInterface {
bool isActive,
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 {

View File

@ -11,6 +11,22 @@ import { Helpers } from "./helpers.sol";
contract MigrateResolver is Helpers, Events {
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 {
require(msg.sender == instaIndex.master(), "not-master");
require(_target != address(0), "target-invalid");
@ -39,19 +55,23 @@ contract MigrateResolver is Helpers, Events {
for (uint256 i = 0; i < _length; i++) {
require(isSupportedToken[tokens[i]], "token-not-enabled");
uint _amt;
address _token = tokens[i];
if (_token == maticAddr) {
bool isMatic = tokens[i] == maticAddr;
address _token = isMatic ? wmaticAddr : tokens[i];
IERC20 tokenContract = IERC20(_token);
if (isMatic) {
require(msg.value == amts[i]);
_amt = msg.value;
TokenInterface(wmaticAddr).deposit{value: msg.value}();
aave.deposit(wmaticAddr, _amt, address(this), 3288);
_amt = msg.value;
} else {
IERC20 tokenContract = IERC20(_token);
_amt = amts[i] == uint(-1) ? tokenContract.balanceOf(msg.sender) : amts[i];
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;
deposits[msg.sender][_token] += _amt;
@ -71,7 +91,8 @@ contract MigrateResolver is Helpers, Events {
for (uint256 i = 0; i < _length; i++) {
require(isSupportedToken[tokens[i]], "token-not-enabled");
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];
if (_amt > maxAmt) {
@ -80,14 +101,20 @@ contract MigrateResolver is Helpers, Events {
deposits[msg.sender][_token] = sub(maxAmt, _amt);
if (_token == maticAddr) {
if (isMatic) {
TokenInterface _tokenContract = TokenInterface(wmaticAddr);
uint _maticBal = address(this).balance;
uint _tknBal = _tokenContract.balanceOf(address(this));
if ((_maticBal + _tknBal) < _amt) {
aave.withdraw(wmaticAddr, sub(_amt, (_tknBal + _maticBal)), address(this));
if (_maticBal > _amt) {
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}("");
} else {
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();
// TODO: emit event
emit LogAaveV2Migrate(dsa, supplyTokens, borrowTokens, supplyAmts, supplyAmts);
}
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
positions[stateId] = receivedData;
// TODO: add event
emit LogStateSync(stateId, receivedData);
}
function migrate(uint _id) external {
@ -191,7 +218,5 @@ contract AaveV2Migrator is MigrateResolver {
_migratePosition(data);
delete positions[_id];
// TODO: add event
}
}

View File

@ -10,7 +10,6 @@ import {
contract Variables {
// 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
// TODO: Add function for flash deposits and withdraw
@ -25,8 +24,7 @@ contract Variables {
/**
* @dev Aave Data Provider
*/
// TODO: add L2 Data provider address
AaveDataProviderInterface constant internal aaveData = AaveDataProviderInterface(address(0));
AaveDataProviderInterface constant internal aaveData = AaveDataProviderInterface(0x7551b5D2763519d4e37e8B81929D336De671d46d);
// dsa => position

View File

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