dsa-polygon-migration/contracts/senders/aave-v2-migrator/main.sol
2021-04-04 13:36:20 +05:30

241 lines
8.6 KiB
Solidity

pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { TokenInterface } from "../../common/interfaces.sol";
import { Helpers } from "./helpers.sol";
import { AaveInterface, ATokenInterface } from "./interfaces.sol";
import { Events } from "./events.sol";
contract LiquidityResolver is Helpers, Events {
using SafeERC20 for IERC20;
mapping(address => mapping(address => uint)) deposits;
function deposit(address[] calldata tokens, uint[] calldata amts) external payable {
uint _length = tokens.length;
require(_length == amts.length, "invalid-length");
uint[] memory _amts = new uint[](_length);
for (uint256 i = 0; i < _length; i++) {
uint _amt;
address _token = tokens[i];
if (_token == ethAddr) {
require(msg.value == amts[i]);
_amt = msg.value;
TokenInterface(wethAddr).deposit{value: 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);
}
_amts[i] = _amt;
deposits[msg.sender][_token] = _amt;
}
emit LogDeposit(msg.sender, tokens, _amts);
}
function withdraw(address[] calldata tokens, uint[] calldata amts) external {
uint _length = tokens.length;
require(_length == amts.length, "invalid-length");
uint[] memory _amts = new uint[](_length);
for (uint256 i = 0; i < _length; i++) {
uint _amt = amts[i];
address _token = tokens[i];
uint maxAmt = deposits[msg.sender][_token];
if (_amt > maxAmt) {
_amt = maxAmt;
}
if (_token == ethAddr) {
TokenInterface(wethAddr).withdraw(_amt);
msg.sender.call{value: _amt}("");
} else {
IERC20(_token).safeTransfer(msg.sender, _amt);
}
_amts[i] = _amt;
deposits[msg.sender][_token] = sub(maxAmt, _amt);
}
emit LogWithdraw(msg.sender, tokens, _amts);
}
}
contract MigrateResolver is LiquidityResolver {
using SafeERC20 for IERC20;
struct AaveData {
bool isFinal;
address targetDsa;
uint[] supplyAmts;
uint[] variableBorrowAmts;
uint[] stableBorrowAmts;
address[] supplyTokens;
address[] borrowTokens;
}
mapping (address => AaveData) public positions;
function migrate(address owner, AaveData calldata _data) external {
require(_data.supplyTokens.length > 0, "0-length-not-allowed");
require(_data.targetDsa != address(0), "invalid-address");
require(_data.supplyTokens.length == _data.supplyAmts.length, "invalid-length");
require(
_data.borrowTokens.length == _data.variableBorrowAmts.length &&
_data.borrowTokens.length == _data.stableBorrowAmts.length,
"invalid-length"
);
AaveData memory data;
data.borrowTokens = _data.borrowTokens;
data.isFinal = _data.isFinal;
data.stableBorrowAmts = _data.stableBorrowAmts;
data.supplyAmts = _data.supplyAmts;
data.supplyTokens = _data.supplyTokens;
data.targetDsa = _data.targetDsa;
data.variableBorrowAmts = _data.variableBorrowAmts;
address sourceDsa = msg.sender;
AaveInterface aave = AaveInterface(aaveProvider.getLendingPool());
(,,,,,uint healthFactor) = aave.getUserAccountData(sourceDsa);
require(healthFactor > 1e18, "position-not-safe");
for (uint i = 0; i < data.supplyTokens.length; i++) {
(address _aToken, ,) = aaveData.getReserveTokensAddresses(data.supplyTokens[i]);
ATokenInterface aTokenContract = ATokenInterface(_aToken);
aTokenContract.transferFrom(msg.sender, address(this), data.supplyAmts[i]);
}
for (uint i = 0; i < data.borrowTokens.length; i++) {
address _token = data.borrowTokens[i] == ethAddr ? wethAddr : data.borrowTokens[i];
data.borrowTokens[i] = _token;
(
,
uint stableDebt,
uint variableDebt,
,,,,,
) = aaveData.getUserReserveData(_token, sourceDsa);
data.stableBorrowAmts[i] = data.stableBorrowAmts[i] == uint(-1) ? stableDebt : data.stableBorrowAmts[i];
data.variableBorrowAmts[i] = data.variableBorrowAmts[i] == uint(-1) ? variableDebt : data.variableBorrowAmts[i];
uint totalBorrowAmt = add(data.stableBorrowAmts[i], data.variableBorrowAmts[i]);
if (totalBorrowAmt > 0) {
IERC20(_token).safeApprove(address(aave), totalBorrowAmt);
}
}
_PaybackStable(data.borrowTokens.length, aave, data.borrowTokens, data.stableBorrowAmts, sourceDsa);
_PaybackVariable(data.borrowTokens.length, aave, data.borrowTokens, data.variableBorrowAmts, sourceDsa);
_Withdraw(data.supplyTokens.length, aave, data.supplyTokens, data.supplyAmts);
positions[owner] = data;
bytes memory positionData = abi.encode(owner, data);
stateSender.syncState(polygonReceiver, positionData);
emit LogAaveV2Migrate(
msg.sender,
data.targetDsa,
data.supplyTokens,
data.borrowTokens,
data.supplyAmts,
data.variableBorrowAmts,
data.stableBorrowAmts
);
}
// function migrate(
// address owner,
// address targetDsa,
// address[] calldata supplyTokens,
// address[] calldata borrowTokens
// ) external {
// require(supplyTokens.length > 0, "0-length-not-allowed");
// require(targetDsa != address(0), "invalid-address");
// address sourceDsa = msg.sender;
// AaveInterface aave = AaveInterface(aaveProvider.getLendingPool());
// AaveData memory data;
// (,,,,,uint healthFactor) = aave.getUserAccountData(sourceDsa);
// require(healthFactor > 1e18, "position-not-safe");
// data.supplyAmts = new uint[](supplyTokens.length);
// data.supplyTokens = new address[](supplyTokens.length);
// data.targetDsa = targetDsa;
// for (uint i = 0; i < supplyTokens.length; i++) {
// address _token = supplyTokens[i] == ethAddr ? wethAddr : supplyTokens[i];
// (address _aToken, ,) = aaveData.getReserveTokensAddresses(_token);
// ATokenInterface aTokenContract = ATokenInterface(_aToken);
// data.supplyTokens[i] = _token;
// data.supplyAmts[i] = aTokenContract.balanceOf(sourceDsa);
// aTokenContract.transferFrom(msg.sender, address(this), data.supplyAmts[i]);
// }
// if (borrowTokens.length > 0) {
// data.variableBorrowAmts = new uint[](borrowTokens.length);
// data.stableBorrowAmts = new uint[](borrowTokens.length);
// for (uint i = 0; i < borrowTokens.length; i++) {
// address _token = borrowTokens[i] == ethAddr ? wethAddr : borrowTokens[i];
// data.borrowTokens[i] = _token;
// (
// ,
// data.stableBorrowAmts[i],
// data.variableBorrowAmts[i],
// ,,,,,
// ) = aaveData.getUserReserveData(_token, sourceDsa);
// uint totalBorrowAmt = add(data.stableBorrowAmts[i], data.variableBorrowAmts[i]);
// if (totalBorrowAmt > 0) {
// IERC20(_token).safeApprove(address(aave), totalBorrowAmt);
// }
// }
// _PaybackStable(borrowTokens.length, aave, data.borrowTokens, data.stableBorrowAmts, sourceDsa);
// _PaybackVariable(borrowTokens.length, aave, data.borrowTokens, data.variableBorrowAmts, sourceDsa);
// }
// _Withdraw(supplyTokens.length, aave, data.supplyTokens, data.supplyAmts);
// positions[owner] = data;
// bytes memory positionData = abi.encode(owner, data);
// stateSender.syncState(polygonReceiver, positionData);
// emit LogAaveV2Migrate(
// msg.sender,
// targetDsa,
// supplyTokens,
// borrowTokens,
// data.supplyAmts,
// data.variableBorrowAmts,
// data.stableBorrowAmts
// );
// }
}