mirror of
https://github.com/Instadapp/dsa-polygon-migration.git
synced 2024-07-29 22:27:58 +00:00
merged mubaris fixes
This commit is contained in:
commit
587f3de38c
3
.env.example
Normal file
3
.env.example
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
ALCHEMY_ID="<>"
|
||||||
|
ETHERSCAN="<>"
|
||||||
|
PRIVATE_KEY="<>"
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -3,3 +3,5 @@ node_modules
|
||||||
#Hardhat files
|
#Hardhat files
|
||||||
cache
|
cache
|
||||||
artifacts
|
artifacts
|
||||||
|
|
||||||
|
.env
|
|
@ -18,7 +18,7 @@ abstract contract Stores {
|
||||||
/**
|
/**
|
||||||
* @dev Return memory variable address
|
* @dev Return memory variable address
|
||||||
*/
|
*/
|
||||||
MemoryInterface constant internal instaMemory = MemoryInterface(address(0)); // TODO: memory address on Polygon
|
MemoryInterface constant internal instaMemory = MemoryInterface(0x6C7256cf7C003dD85683339F75DdE9971f98f2FD);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev Get Uint value from InstaMemory Contract.
|
* @dev Get Uint value from InstaMemory Contract.
|
||||||
|
|
|
@ -13,4 +13,28 @@ contract Events {
|
||||||
address[] tokens,
|
address[] tokens,
|
||||||
uint[] amts
|
uint[] amts
|
||||||
);
|
);
|
||||||
|
|
||||||
|
event LogUpdateSafeRatioGap(
|
||||||
|
uint256 oldSafeRatioGap,
|
||||||
|
uint256 newSafeRatioGap
|
||||||
|
);
|
||||||
|
|
||||||
|
event LogAddSupportedTokens(
|
||||||
|
address[] tokens
|
||||||
|
);
|
||||||
|
|
||||||
|
event LogSettle();
|
||||||
|
|
||||||
|
event LogAaveV2Migrate(
|
||||||
|
address indexed user,
|
||||||
|
address[] supplyTokens,
|
||||||
|
address[] borrowTokens,
|
||||||
|
uint256[] supplyAmts,
|
||||||
|
uint256[] borrowAmts
|
||||||
|
);
|
||||||
|
|
||||||
|
event LogStateSync(
|
||||||
|
uint256 indexed stateId,
|
||||||
|
bytes data
|
||||||
|
);
|
||||||
}
|
}
|
|
@ -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 = borrowTokens[i] == maticAddr ? wmaticAddr : borrowTokens[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;
|
||||||
|
@ -124,7 +127,7 @@ 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("withdraw(address,uint256,address,uint256,uint256)", _atoken, _borrowAmt, address(this), 0, 0); // encode the data of atoken withdrawal
|
castData[spellsAmt] = abi.encode("withdraw(address,uint256,address,uint256,uint256)", _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));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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");
|
||||||
|
@ -27,6 +43,7 @@ contract MigrateResolver is Helpers, Events {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: change deposit to single token at once as msg.value == amt[i] can lead to double ETH deposit
|
||||||
function deposit(address[] calldata tokens, uint[] calldata amts) external payable {
|
function deposit(address[] calldata tokens, uint[] calldata amts) external payable {
|
||||||
uint _length = tokens.length;
|
uint _length = tokens.length;
|
||||||
require(_length == amts.length, "invalid-length");
|
require(_length == amts.length, "invalid-length");
|
||||||
|
@ -38,21 +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]);
|
||||||
|
TokenInterface(_token).deposit{value: msg.value}();
|
||||||
_amt = msg.value;
|
_amt = msg.value;
|
||||||
TokenInterface(wmaticAddr).deposit{value: msg.value}();
|
|
||||||
TokenInterface(wmaticAddr).approve(address(aave), _amt);
|
|
||||||
aave.deposit(wmaticAddr, _amt, address(this), 3288);
|
|
||||||
} 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);
|
||||||
tokenContract.approve(address(aave), _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;
|
||||||
|
@ -61,6 +80,7 @@ contract MigrateResolver is Helpers, Events {
|
||||||
emit LogDeposit(msg.sender, tokens, _amts);
|
emit LogDeposit(msg.sender, tokens, _amts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: change withdraw to single token at once as msg.value == amt[i] can lead to double ETH deposit
|
||||||
function withdraw(address[] calldata tokens, uint[] calldata amts) external {
|
function withdraw(address[] calldata tokens, uint[] calldata amts) external {
|
||||||
uint _length = tokens.length;
|
uint _length = tokens.length;
|
||||||
require(_length == amts.length, "invalid-length");
|
require(_length == amts.length, "invalid-length");
|
||||||
|
@ -72,7 +92,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) {
|
||||||
|
@ -81,7 +102,7 @@ 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));
|
||||||
|
@ -90,6 +111,7 @@ contract MigrateResolver is Helpers, Events {
|
||||||
}
|
}
|
||||||
_tokenContract.withdraw((sub(_amt, _maticBal)));
|
_tokenContract.withdraw((sub(_amt, _maticBal)));
|
||||||
msg.sender.call{value: _amt}("");
|
msg.sender.call{value: _amt}("");
|
||||||
|
_amts[i] = _amt;
|
||||||
} else {
|
} else {
|
||||||
IERC20 _tokenContract = IERC20(_token);
|
IERC20 _tokenContract = IERC20(_token);
|
||||||
uint _tknBal = _tokenContract.balanceOf(address(this));
|
uint _tknBal = _tokenContract.balanceOf(address(this));
|
||||||
|
@ -140,7 +162,7 @@ contract MigrateResolver is Helpers, Events {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: emit event
|
emit LogSettle();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -168,7 +190,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 {
|
||||||
|
@ -179,7 +201,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 {
|
||||||
|
@ -192,7 +214,5 @@ contract AaveV2Migrator is MigrateResolver {
|
||||||
_migratePosition(data);
|
_migratePosition(data);
|
||||||
|
|
||||||
delete positions[_id];
|
delete positions[_id];
|
||||||
|
|
||||||
// TODO: add event
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,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
|
||||||
|
|
|
@ -5,13 +5,18 @@ contract Events {
|
||||||
event LogDeposit(
|
event LogDeposit(
|
||||||
address owner,
|
address owner,
|
||||||
address[] tokens,
|
address[] tokens,
|
||||||
uint[] amts
|
uint256[] amts
|
||||||
);
|
);
|
||||||
|
|
||||||
event LogWithdraw(
|
event LogWithdraw(
|
||||||
address owner,
|
address owner,
|
||||||
address[] tokens,
|
address[] tokens,
|
||||||
uint[] amts
|
uint256[] amts
|
||||||
|
);
|
||||||
|
|
||||||
|
event LogSettle(
|
||||||
|
address[] tokens,
|
||||||
|
uint256[] amts
|
||||||
);
|
);
|
||||||
|
|
||||||
event LogAaveV2Migrate(
|
event LogAaveV2Migrate(
|
||||||
|
@ -19,9 +24,20 @@ contract Events {
|
||||||
address indexed targetDsa,
|
address indexed targetDsa,
|
||||||
address[] supplyTokens,
|
address[] supplyTokens,
|
||||||
address[] borrowTokens,
|
address[] borrowTokens,
|
||||||
uint[] supplyAmts,
|
uint256[] supplyAmts,
|
||||||
uint[] variableBorrowAmts,
|
uint256[] variableBorrowAmts,
|
||||||
uint[] stableBorrowAmts
|
uint256[] stableBorrowAmts
|
||||||
|
);
|
||||||
|
|
||||||
|
event LogUpdateVariables(
|
||||||
|
uint256 oldFee,
|
||||||
|
uint256 newFee,
|
||||||
|
uint256 oldSafeRatioGap,
|
||||||
|
uint256 newSafeRatioGap
|
||||||
|
);
|
||||||
|
|
||||||
|
event LogAddSupportedTokens(
|
||||||
|
uint256[] tokens
|
||||||
);
|
);
|
||||||
|
|
||||||
event LogAddTokensSupport(address[] _tokens);
|
event LogAddTokensSupport(address[] _tokens);
|
||||||
|
|
|
@ -15,13 +15,43 @@ import {
|
||||||
ATokenInterface,
|
ATokenInterface,
|
||||||
StateSenderInterface,
|
StateSenderInterface,
|
||||||
AavePriceOracle,
|
AavePriceOracle,
|
||||||
ChainLinkInterface
|
ChainLinkInterface,
|
||||||
|
ReserveConfigurationMap
|
||||||
} from "./interfaces.sol";
|
} from "./interfaces.sol";
|
||||||
|
|
||||||
abstract contract Helpers is DSMath, Stores, Variables {
|
abstract contract Helpers is DSMath, Stores, Variables {
|
||||||
|
using SafeERC20 for IERC20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Aave reserve configuration bit masks
|
||||||
|
*/
|
||||||
|
uint256 constant LIQUIDATION_THRESHOLD_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF;
|
||||||
|
uint256 constant DECIMALS_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF;
|
||||||
|
uint256 constant LIQUIDATION_THRESHOLD_START_BIT_POSITION = 16;
|
||||||
|
uint256 constant RESERVE_DECIMALS_START_BIT_POSITION = 48;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Additional math helpers
|
||||||
|
*/
|
||||||
|
uint256 constant PERCENTAGE_FACTOR = 1e4; //percentage plus two decimals
|
||||||
|
uint256 constant HALF_PERCENT = PERCENTAGE_FACTOR / 2;
|
||||||
|
|
||||||
|
// function percentMul(uint256 value, uint256 percentage) internal pure returns (uint256) {
|
||||||
|
// if (value == 0 || percentage == 0) {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// require(
|
||||||
|
// value <= (type(uint256).max - HALF_PERCENT) / percentage,
|
||||||
|
// "percent-mul-overflow"
|
||||||
|
// );
|
||||||
|
|
||||||
|
// return (value * percentage + HALF_PERCENT) / PERCENTAGE_FACTOR;
|
||||||
|
// }
|
||||||
|
|
||||||
function _paybackBehalfOne(AaveInterface aave, address token, uint amt, uint rateMode, address user) private {
|
function _paybackBehalfOne(AaveInterface aave, address token, uint amt, uint rateMode, address user) private {
|
||||||
aave.repay(token, amt, rateMode, user);
|
address _token = token == ethAddr ? wethAddr : token;
|
||||||
|
aave.repay(_token, amt, rateMode, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _PaybackStable(
|
function _PaybackStable(
|
||||||
|
@ -70,16 +100,17 @@ abstract contract Helpers is DSMath, Stores, Variables {
|
||||||
|
|
||||||
totalBorrow[i] = add(stableBorrow[i], variableBorrow[i]);
|
totalBorrow[i] = add(stableBorrow[i], variableBorrow[i]);
|
||||||
if (totalBorrow[i] > 0) {
|
if (totalBorrow[i] > 0) {
|
||||||
IERC20(_token).approve(address(aave), totalBorrow[i]);
|
IERC20(_token).safeApprove(address(aave), totalBorrow[i]);
|
||||||
}
|
}
|
||||||
aave.borrow(_token, totalBorrow[i], 2, 3088, address(this));
|
aave.borrow(_token, totalBorrow[i], 2, 3288, address(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _getAtokens(address dsa, address[] memory supplyTokens, uint[] memory supplyAmts) internal returns (uint[] memory finalAmts) {
|
function _getAtokens(address dsa, address[] memory supplyTokens, uint[] memory supplyAmts) internal returns (uint[] memory finalAmts) {
|
||||||
for (uint i = 0; i < supplyTokens.length; i++) {
|
for (uint i = 0; i < supplyTokens.length; i++) {
|
||||||
require(isSupportedToken[supplyTokens[i]], "token-not-enabled");
|
require(isSupportedToken[supplyTokens[i]], "token-not-enabled");
|
||||||
(address _aToken, ,) = aaveData.getReserveTokensAddresses(supplyTokens[i]);
|
address _token = supplyTokens[i] == ethAddr ? wethAddr : supplyTokens[i];
|
||||||
|
(address _aToken, ,) = aaveData.getReserveTokensAddresses(_token);
|
||||||
ATokenInterface aTokenContract = ATokenInterface(_aToken);
|
ATokenInterface aTokenContract = ATokenInterface(_aToken);
|
||||||
uint _finalAmt;
|
uint _finalAmt;
|
||||||
if (supplyAmts[i] == uint(-1)) {
|
if (supplyAmts[i] == uint(-1)) {
|
||||||
|
@ -96,10 +127,16 @@ abstract contract Helpers is DSMath, Stores, Variables {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// function _getParams(uint config) internal returns (
|
||||||
|
// uint liqudationThreshold, uint decimals
|
||||||
|
// ) {
|
||||||
|
// liqudationThreshold = (config & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION;
|
||||||
|
// decimals = (config & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION;
|
||||||
|
// }
|
||||||
|
|
||||||
function isPositionSafe() internal returns (bool isOk) {
|
function isPositionSafe() internal returns (bool isOk) {
|
||||||
AaveInterface aave = AaveInterface(aaveProvider.getLendingPool());
|
AaveInterface aave = AaveInterface(aaveProvider.getLendingPool());
|
||||||
(,,,,,uint healthFactor) = aave.getUserAccountData(address(this));
|
(,,,,,uint healthFactor) = aave.getUserAccountData(address(this));
|
||||||
// TODO: Check throughly minLimit = 100%/80% = 125% (20% gap initially)
|
|
||||||
uint minLimit = wdiv(1e18, safeRatioGap);
|
uint minLimit = wdiv(1e18, safeRatioGap);
|
||||||
isOk = healthFactor > minLimit;
|
isOk = healthFactor > minLimit;
|
||||||
require(isOk, "position-at-risk");
|
require(isOk, "position-at-risk");
|
||||||
|
@ -116,7 +153,7 @@ abstract contract Helpers is DSMath, Stores, Variables {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertTo18(uint amount, uint decimal) internal returns (uint) {
|
function convertTo18(uint amount, uint decimal) internal view returns (uint) {
|
||||||
return amount * (10 ** (18 - decimal)); // TODO: verify this
|
return amount * (10 ** (18 - decimal)); // TODO: verify this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,6 +161,7 @@ abstract contract Helpers is DSMath, Stores, Variables {
|
||||||
/*
|
/*
|
||||||
* Checks the position to migrate should have a safe gap from liquidation
|
* Checks the position to migrate should have a safe gap from liquidation
|
||||||
*/
|
*/
|
||||||
|
// TODO: which checkRatio to use?
|
||||||
function _checkRatio(AaveData memory data) public {
|
function _checkRatio(AaveData memory data) public {
|
||||||
uint[] memory supplyTokenPrices = getTokensPrices(data.supplyTokens);
|
uint[] memory supplyTokenPrices = getTokensPrices(data.supplyTokens);
|
||||||
(uint[] memory supplyDecimals, uint[] memory supplyLts) = getTokenLt(data.supplyTokens);
|
(uint[] memory supplyDecimals, uint[] memory supplyLts) = getTokenLt(data.supplyTokens);
|
||||||
|
@ -146,4 +184,37 @@ abstract contract Helpers is DSMath, Stores, Variables {
|
||||||
require(netBorrow < sub(liquidation, _dif), "position-is-risky-to-migrate");
|
require(netBorrow < sub(liquidation, _dif), "position-is-risky-to-migrate");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// function _checkRatio(AaveData memory data) public returns (bool isOk) {
|
||||||
|
// uint totalCollateral;
|
||||||
|
// uint totalDebt;
|
||||||
|
// uint avgLiquidationThresold;
|
||||||
|
|
||||||
|
// for(uint i = 0; i < data.supplyTokens.length; i++) {
|
||||||
|
// address _token = data.supplyTokens[i] == ethAddr ? wethAddr : data.supplyTokens[i];
|
||||||
|
// ReserveConfigurationMap memory config = aave.getConfiguration(_token);
|
||||||
|
// (uint _liq, uint _dec) = _getParams(config.data);
|
||||||
|
// uint assetPrice = aaveOracle.getAssetPrice(_token);
|
||||||
|
// uint collateral = div(mul(assetPrice, data.supplyAmts[i]), 10**_dec);
|
||||||
|
// totalCollateral += collateral;
|
||||||
|
// avgLiquidationThresold += mul(collateral, _liq);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for(uint i = 0; data.borrowTokens.length; i++) {
|
||||||
|
// address _token = data.supplyTokens[i] == ethAddr ? wethAddr : data.supplyTokens[i];
|
||||||
|
// ReserveConfigurationMap memory config = aave.getConfiguration(_token);
|
||||||
|
// (, uint _dec) = _getParams(config.data);
|
||||||
|
// uint assetPrice = aaveOracle.getAssetPrice(_token);
|
||||||
|
// uint debt = div(mul(assetPrice, data.borrowAmts[i]), 10**_dec);
|
||||||
|
// totalDebt += debt;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (totalCollateral > 0) {
|
||||||
|
// avgLiquidationThresold = div(avgLiquidationThresold, totalCollateral);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// uint healthFactor = wdiv(percentMul(totalCollateral, avgLiquidationThresold), totalDebt);
|
||||||
|
// uint minLimit = wdiv(1e18, safeRatioGap);
|
||||||
|
// isOk = healthFactor > minLimit;
|
||||||
|
// require(isOk, "position-at-risk");
|
||||||
|
// }
|
||||||
}
|
}
|
|
@ -1,6 +1,20 @@
|
||||||
pragma solidity >=0.7.0;
|
pragma solidity >=0.7.0;
|
||||||
pragma experimental ABIEncoderV2;
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
struct ReserveConfigurationMap {
|
||||||
|
//bit 0-15: LTV
|
||||||
|
//bit 16-31: Liq. threshold
|
||||||
|
//bit 32-47: Liq. bonus
|
||||||
|
//bit 48-55: Decimals
|
||||||
|
//bit 56: Reserve is active
|
||||||
|
//bit 57: reserve is frozen
|
||||||
|
//bit 58: borrowing is enabled
|
||||||
|
//bit 59: stable rate borrowing enabled
|
||||||
|
//bit 60-63: reserved
|
||||||
|
//bit 64-79: reserve factor
|
||||||
|
uint256 data;
|
||||||
|
}
|
||||||
|
|
||||||
interface AaveInterface {
|
interface AaveInterface {
|
||||||
function deposit(address _asset, uint256 _amount, address _onBehalfOf, uint16 _referralCode) external;
|
function deposit(address _asset, uint256 _amount, address _onBehalfOf, uint16 _referralCode) external;
|
||||||
function withdraw(address _asset, uint256 _amount, address _to) external;
|
function withdraw(address _asset, uint256 _amount, address _to) external;
|
||||||
|
@ -21,6 +35,10 @@ interface AaveInterface {
|
||||||
uint256 ltv,
|
uint256 ltv,
|
||||||
uint256 healthFactor
|
uint256 healthFactor
|
||||||
);
|
);
|
||||||
|
function getConfiguration(address asset)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (ReserveConfigurationMap memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AaveLendingPoolProviderInterface {
|
interface AaveLendingPoolProviderInterface {
|
||||||
|
@ -72,6 +90,13 @@ interface ATokenInterface {
|
||||||
function approve(address, uint256) external;
|
function approve(address, uint256) external;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface AaveOracleInterface {
|
||||||
|
function getAssetPrice(address _asset) external view returns (uint256);
|
||||||
|
function getAssetsPrices(address[] calldata _assets) external view returns(uint256[] memory);
|
||||||
|
function getSourceOfAsset(address _asset) external view returns(address);
|
||||||
|
function getFallbackOracle() external view returns(address);
|
||||||
|
}
|
||||||
|
|
||||||
interface StateSenderInterface {
|
interface StateSenderInterface {
|
||||||
function syncState(address receiver, bytes calldata data) external;
|
function syncState(address receiver, bytes calldata data) external;
|
||||||
function register(address sender, address receiver) external;
|
function register(address sender, address receiver) external;
|
||||||
|
@ -98,11 +123,5 @@ interface ChainLinkInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RootChainManagerInterface {
|
interface RootChainManagerInterface {
|
||||||
function depositEtherFor(address user) external payable;
|
function depositFor(address user, address token, bytes calldata depositData) external;
|
||||||
function depositFor(
|
|
||||||
address user,
|
|
||||||
address rootToken,
|
|
||||||
bytes calldata depositData
|
|
||||||
) external;
|
|
||||||
function exit(bytes calldata inputData) external;
|
|
||||||
}
|
}
|
|
@ -22,10 +22,11 @@ contract LiquidityResolver is Helpers, Events {
|
||||||
function addTokenSupport(address[] memory _tokens) public {
|
function addTokenSupport(address[] memory _tokens) public {
|
||||||
require(msg.sender == instaIndex.master(), "not-master");
|
require(msg.sender == instaIndex.master(), "not-master");
|
||||||
for (uint i = 0; i < _tokens.length; i++) {
|
for (uint i = 0; i < _tokens.length; i++) {
|
||||||
|
require(!isSupportedToken[_tokens[i]], "already-added");
|
||||||
isSupportedToken[_tokens[i]] = true;
|
isSupportedToken[_tokens[i]] = true;
|
||||||
|
supportedTokens.push(_tokens[i]);
|
||||||
}
|
}
|
||||||
supportedTokens = _tokens;
|
emit LogAddSupportedTokens(_tokens);
|
||||||
emit LogAddTokensSupport(_tokens);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function spell(address _target, bytes memory _data) external {
|
function spell(address _target, bytes memory _data) external {
|
||||||
|
@ -56,21 +57,23 @@ contract LiquidityResolver 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 isEth = tokens[i] == ethAddr;
|
||||||
if (_token == ethAddr) {
|
address _token = isEth ? wethAddr : tokens[i];
|
||||||
|
|
||||||
|
IERC20 tokenContract = IERC20(_token);
|
||||||
|
|
||||||
|
if (isEth) {
|
||||||
require(msg.value == amts[i]);
|
require(msg.value == amts[i]);
|
||||||
|
TokenInterface(wethAddr).deposit{value: msg.value}();
|
||||||
_amt = msg.value;
|
_amt = msg.value;
|
||||||
TokenInterface(wethAddr).deposit{value: _amt}();
|
|
||||||
TokenInterface(wethAddr).approve(address(aave), _amt);
|
|
||||||
aave.deposit(wethAddr, _amt, address(this), 3288);
|
|
||||||
} 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);
|
||||||
tokenContract.approve(address(aave), _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;
|
||||||
|
@ -91,7 +94,8 @@ contract LiquidityResolver 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 isEth = tokens[i] == ethAddr;
|
||||||
|
address _token = isEth ? wethAddr : tokens[i];
|
||||||
uint maxAmt = deposits[msg.sender][_token];
|
uint maxAmt = deposits[msg.sender][_token];
|
||||||
|
|
||||||
if (_amt > maxAmt) {
|
if (_amt > maxAmt) {
|
||||||
|
@ -100,10 +104,16 @@ contract LiquidityResolver is Helpers, Events {
|
||||||
|
|
||||||
deposits[msg.sender][_token] = sub(maxAmt, _amt);
|
deposits[msg.sender][_token] = sub(maxAmt, _amt);
|
||||||
|
|
||||||
if (_token == ethAddr) {
|
if (isEth) {
|
||||||
TokenInterface _tokenContract = TokenInterface(wethAddr);
|
TokenInterface _tokenContract = TokenInterface(wethAddr);
|
||||||
uint _ethBal = address(this).balance;
|
uint _ethBal = address(this).balance;
|
||||||
uint _tknBal = _tokenContract.balanceOf(address(this));
|
uint _tknBal = _tokenContract.balanceOf(address(this));
|
||||||
|
if (_ethBal > _amt) {
|
||||||
|
msg.sender.call{value: _amt}("");
|
||||||
|
_amts[i] = _amt;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ((_ethBal + _tknBal) < _amt) {
|
if ((_ethBal + _tknBal) < _amt) {
|
||||||
aave.withdraw(wethAddr, sub(_amt, (_tknBal + _ethBal)), address(this));
|
aave.withdraw(wethAddr, sub(_amt, (_tknBal + _ethBal)), address(this));
|
||||||
}
|
}
|
||||||
|
@ -144,7 +154,7 @@ contract LiquidityResolver is Helpers, Events {
|
||||||
IERC20 _tokenContract = IERC20(_token);
|
IERC20 _tokenContract = IERC20(_token);
|
||||||
uint _tokenBal = _tokenContract.balanceOf(address(this));
|
uint _tokenBal = _tokenContract.balanceOf(address(this));
|
||||||
if (_tokenBal > 0) {
|
if (_tokenBal > 0) {
|
||||||
_tokenContract.approve(address(this), _tokenBal);
|
_tokenContract.safeApprove(address(this), _tokenBal);
|
||||||
aave.deposit(_token, _tokenBal, address(this), 3288);
|
aave.deposit(_token, _tokenBal, address(this), 3288);
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
|
@ -155,21 +165,25 @@ contract LiquidityResolver is Helpers, Events {
|
||||||
if (supplyBal != 0 && borrowBal != 0) {
|
if (supplyBal != 0 && borrowBal != 0) {
|
||||||
if (supplyBal > borrowBal) {
|
if (supplyBal > borrowBal) {
|
||||||
aave.withdraw(_token, borrowBal, address(this)); // TODO: fail because of not enough withdrawing capacity?
|
aave.withdraw(_token, borrowBal, address(this)); // TODO: fail because of not enough withdrawing capacity?
|
||||||
IERC20(_token).approve(address(aave), borrowBal);
|
IERC20(_token).safeApprove(address(aave), borrowBal);
|
||||||
aave.repay(_token, borrowBal, 2, address(this));
|
aave.repay(_token, borrowBal, 2, address(this));
|
||||||
} else {
|
} else {
|
||||||
aave.withdraw(_token, supplyBal, address(this)); // TODO: fail because of not enough withdrawing capacity?
|
aave.withdraw(_token, supplyBal, address(this)); // TODO: fail because of not enough withdrawing capacity?
|
||||||
IERC20(_token).approve(address(aave), supplyBal);
|
IERC20(_token).safeApprove(address(aave), supplyBal);
|
||||||
aave.repay(_token, supplyBal, 2, address(this));
|
aave.repay(_token, supplyBal, 2, address(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (uint i = 0; i < _tokens.length; i++) {
|
for (uint i = 0; i < _tokens.length; i++) {
|
||||||
aave.withdraw(_tokens[i], _amts[i], address(this));
|
address _token = _tokens[i] == ethAddr ? wethAddr : _tokens[i];
|
||||||
migrator.depositFor(polygonReceiver, _tokens[i], abi.encode(_amts[i]));
|
aave.withdraw(_token, _amts[i], address(this));
|
||||||
|
// TODO: Verify this
|
||||||
|
IERC20(_token).safeApprove(erc20Predicate, _amts[i]);
|
||||||
|
rootChainManager.depositFor(polygonReceiver, _token, abi.encode(_amts[i]));
|
||||||
|
|
||||||
isPositionSafe();
|
isPositionSafe();
|
||||||
}
|
}
|
||||||
emit settle(_tokens, _amts);
|
emit LogSettle(_tokens, _amts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ pragma solidity ^0.7.0;
|
||||||
import {
|
import {
|
||||||
AaveLendingPoolProviderInterface,
|
AaveLendingPoolProviderInterface,
|
||||||
AaveDataProviderInterface,
|
AaveDataProviderInterface,
|
||||||
|
AaveOracleInterface,
|
||||||
StateSenderInterface,
|
StateSenderInterface,
|
||||||
IndexInterface,
|
IndexInterface,
|
||||||
FlashloanInterface,
|
FlashloanInterface,
|
||||||
|
@ -40,6 +41,7 @@ contract Variables {
|
||||||
|
|
||||||
address constant internal polygonReceiver = address(0); // TODO: Replace this
|
address constant internal polygonReceiver = address(0); // TODO: Replace this
|
||||||
FlashloanInterface constant internal flashloanContract = FlashloanInterface(address(0)); // TODO: Replace this
|
FlashloanInterface constant internal flashloanContract = FlashloanInterface(address(0)); // TODO: Replace this
|
||||||
|
address constant internal erc20Predicate = 0x40ec5B33f54e0E8A33A975908C5BA1c14e5BbbDf;
|
||||||
|
|
||||||
// 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?
|
// TODO: Is this number correct for it?
|
||||||
|
@ -59,6 +61,11 @@ contract Variables {
|
||||||
*/
|
*/
|
||||||
AaveDataProviderInterface constant internal aaveData = AaveDataProviderInterface(0x057835Ad21a177dbdd3090bB1CAE03EaCF78Fc6d);
|
AaveDataProviderInterface constant internal aaveData = AaveDataProviderInterface(0x057835Ad21a177dbdd3090bB1CAE03EaCF78Fc6d);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Aave Price Oracle
|
||||||
|
*/
|
||||||
|
AaveOracleInterface constant internal aaveOracle = AaveOracleInterface(0xA50ba011c48153De246E5192C8f9258A2ba79Ca9);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev Polygon State Sync Contract
|
* @dev Polygon State Sync Contract
|
||||||
*/
|
*/
|
||||||
|
@ -70,6 +77,9 @@ contract Variables {
|
||||||
// InstaIndex Address.
|
// InstaIndex Address.
|
||||||
IndexInterface public constant instaIndex = IndexInterface(0x2971AdFa57b20E5a416aE5a708A8655A9c74f723);
|
IndexInterface public constant instaIndex = IndexInterface(0x2971AdFa57b20E5a416aE5a708A8655A9c74f723);
|
||||||
|
|
||||||
RootChainManagerInterface internal constant migrator = RootChainManagerInterface(0xA0c68C638235ee32657e8f720a23ceC1bFc77C77);
|
/**
|
||||||
|
* Polygon deposit bridge
|
||||||
|
*/
|
||||||
|
RootChainManagerInterface public constant rootChainManager = RootChainManagerInterface(0xA0c68C638235ee32657e8f720a23ceC1bFc77C77);
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,14 +1,10 @@
|
||||||
|
require("@nomiclabs/hardhat-ethers");
|
||||||
require("@nomiclabs/hardhat-waffle");
|
require("@nomiclabs/hardhat-waffle");
|
||||||
|
require("@nomiclabs/hardhat-etherscan");
|
||||||
|
|
||||||
// This is a sample Hardhat task. To learn how to create your own go to
|
require("dotenv").config();
|
||||||
// https://hardhat.org/guides/create-task.html
|
const ALCHEMY_ID = process.env.ALCHEMY_ID;
|
||||||
task("accounts", "Prints the list of accounts", async () => {
|
const PRIVATE_KEY = process.env.PRIVATE_KEY;
|
||||||
const accounts = await ethers.getSigners();
|
|
||||||
|
|
||||||
for (const account of accounts) {
|
|
||||||
console.log(account.address);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// You need to export an object to set up your config
|
// You need to export an object to set up your config
|
||||||
// Go to https://hardhat.org/config/ to learn more
|
// Go to https://hardhat.org/config/ to learn more
|
||||||
|
@ -18,5 +14,26 @@ task("accounts", "Prints the list of accounts", async () => {
|
||||||
*/
|
*/
|
||||||
module.exports = {
|
module.exports = {
|
||||||
solidity: "0.7.3",
|
solidity: "0.7.3",
|
||||||
|
networks: {
|
||||||
|
hardhat: {
|
||||||
|
forking: {
|
||||||
|
url: `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_ID}`,
|
||||||
|
blockNumber: 12070498,
|
||||||
|
},
|
||||||
|
blockGasLimit: 12000000,
|
||||||
|
},
|
||||||
|
kovan: {
|
||||||
|
url: `https://eth-kovan.alchemyapi.io/v2/${ALCHEMY_ID}`,
|
||||||
|
accounts: [`0x${PRIVATE_KEY}`],
|
||||||
|
gas: 12500000,
|
||||||
|
},
|
||||||
|
polygon: {
|
||||||
|
url: 'https://rpc-mainnet.matic.network',
|
||||||
|
accounts: [`0x${PRIVATE_KEY}`],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
etherscan: {
|
||||||
|
apiKey: process.env.ETHERSCAN
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
16314
package-lock.json
generated
16314
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
|
@ -19,6 +19,8 @@
|
||||||
"solc": "0.7.0"
|
"solc": "0.7.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@openzeppelin/contracts": "^3.4.0-solc-0.7"
|
"@nomiclabs/hardhat-etherscan": "^2.1.1",
|
||||||
|
"@openzeppelin/contracts": "^3.4.0-solc-0.7",
|
||||||
|
"dotenv": "^8.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user