mirror of
https://github.com/Instadapp/dsa-connectors.git
synced 2024-07-29 22:37:00 +00:00
Merge branch 'main' of github.com:Instadapp/dsa-connectors
This commit is contained in:
commit
003ef06887
6
contracts/mainnet/connectors/INST/events.sol
Normal file
6
contracts/mainnet/connectors/INST/events.sol
Normal file
|
@ -0,0 +1,6 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
event LogVoteCast(uint256 proposalId, uint256 support, string reason);
|
||||
event LogDelegate(address delegatee);
|
||||
}
|
18
contracts/mainnet/connectors/INST/helpers.sol
Normal file
18
contracts/mainnet/connectors/INST/helpers.sol
Normal file
|
@ -0,0 +1,18 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import { DSMath } from "../../common/math.sol";
|
||||
import { Basic } from "../../common/basic.sol";
|
||||
import { InstaTokenInterface, InstaGovernorInterface } from "./interface.sol";
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
||||
/**
|
||||
* @dev InstaGovernorBravo
|
||||
*/
|
||||
InstaGovernorInterface internal constant instaGovernor = InstaGovernorInterface(0x0204Cd037B2ec03605CFdFe482D8e257C765fA1B);
|
||||
|
||||
/**
|
||||
* @dev INST Token
|
||||
*/
|
||||
InstaTokenInterface internal constant instToken = InstaTokenInterface(0x6f40d4A6237C257fff2dB00FA0510DeEECd303eb);
|
||||
}
|
10
contracts/mainnet/connectors/INST/interface.sol
Normal file
10
contracts/mainnet/connectors/INST/interface.sol
Normal file
|
@ -0,0 +1,10 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
interface InstaGovernorInterface {
|
||||
function castVoteWithReason(uint proposalId, uint8 support, string calldata reason) external;
|
||||
}
|
||||
|
||||
interface InstaTokenInterface {
|
||||
function delegate(address delegatee) external;
|
||||
function delegates(address) external view returns(address);
|
||||
}
|
60
contracts/mainnet/connectors/INST/main.sol
Normal file
60
contracts/mainnet/connectors/INST/main.sol
Normal file
|
@ -0,0 +1,60 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/**
|
||||
* @title Instadapp Governance.
|
||||
* @dev Governance.
|
||||
*/
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { Stores } from "../../common/stores.sol";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
import { Events } from "./events.sol";
|
||||
|
||||
abstract contract Resolver is Events, Helpers {
|
||||
|
||||
/**
|
||||
* @dev Delegate votes.
|
||||
* @notice Delegating votes to delegatee.
|
||||
* @param delegatee The address to delegate the votes.
|
||||
*/
|
||||
function delegate(address delegatee) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
require(instToken.delegates(address(this)) != delegatee, "Already delegated to same delegatee.");
|
||||
|
||||
instToken.delegate(delegatee);
|
||||
|
||||
_eventName = "LogDelegate(address)";
|
||||
_eventParam = abi.encode(delegatee);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dev Cast vote.
|
||||
* @notice Casting vote for a proposal
|
||||
* @param proposalId The id of the proposal to vote on
|
||||
* @param support The support value for the vote. 0=against, 1=for, 2=abstain
|
||||
*/
|
||||
function voteCast(uint256 proposalId, uint256 support) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
instaGovernor.castVoteWithReason(proposalId, uint8(support), "");
|
||||
|
||||
_eventName = "LogVoteCast(uint256,uint256,string)";
|
||||
_eventParam = abi.encode(proposalId, support, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Cast vote with reason.
|
||||
* @notice Casting vote for a proposal
|
||||
* @param proposalId The id of the proposal to vote on
|
||||
* @param support The support value for the vote. 0=against, 1=for, 2=abstain
|
||||
* @param reason The reason given for the vote
|
||||
*/
|
||||
function voteCastWithReason(uint256 proposalId, uint256 support, string calldata reason) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
instaGovernor.castVoteWithReason(proposalId, uint8(support), reason);
|
||||
|
||||
_eventName = "LogVoteCast(uint256,uint256,string)";
|
||||
_eventParam = abi.encode(proposalId, support, reason);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2InstadappGovernanceBravo is Resolver {
|
||||
string public constant name = "Instadapp-governance-bravo-v1";
|
||||
}
|
|
@ -18,7 +18,13 @@ abstract contract AuthorityResolver is Events, Helpers {
|
|||
function add(
|
||||
address authority
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
AccountInterface(address(this)).enable(authority);
|
||||
require(authority != address(0), "Not-valid-authority");
|
||||
AccountInterface _dsa = AccountInterface(address(this));
|
||||
if (_dsa.isAuth(authority)) {
|
||||
authority = address(0);
|
||||
} else {
|
||||
_dsa.enable(authority);
|
||||
}
|
||||
|
||||
_eventName = "LogAddAuth(address,address)";
|
||||
_eventParam = abi.encode(msg.sender, authority);
|
||||
|
@ -33,7 +39,13 @@ abstract contract AuthorityResolver is Events, Helpers {
|
|||
address authority
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
require(checkAuthCount() > 1, "Removing-all-authorities");
|
||||
AccountInterface(address(this)).disable(authority);
|
||||
require(authority != address(0), "Not-valid-authority");
|
||||
AccountInterface _dsa = AccountInterface(address(this));
|
||||
if (_dsa.isAuth(authority)) {
|
||||
_dsa.disable(authority);
|
||||
} else {
|
||||
authority = address(0);
|
||||
}
|
||||
|
||||
_eventName = "LogRemoveAuth(address,address)";
|
||||
_eventParam = abi.encode(msg.sender, authority);
|
||||
|
@ -41,5 +53,5 @@ abstract contract AuthorityResolver is Events, Helpers {
|
|||
}
|
||||
|
||||
contract ConnectV2Auth is AuthorityResolver {
|
||||
string public constant name = "Auth-v1";
|
||||
string public constant name = "Auth-v1.1";
|
||||
}
|
||||
|
|
30
contracts/mainnet/connectors/erc20_staking/events.sol
Normal file
30
contracts/mainnet/connectors/erc20_staking/events.sol
Normal file
|
@ -0,0 +1,30 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
|
||||
event LogDeposit(
|
||||
address indexed stakingToken,
|
||||
bytes32 indexed stakingType,
|
||||
uint256 amount,
|
||||
uint getId,
|
||||
uint setId
|
||||
);
|
||||
|
||||
event LogWithdrawAndClaimedReward(
|
||||
address indexed stakingToken,
|
||||
bytes32 indexed stakingType,
|
||||
uint256 amount,
|
||||
uint256 rewardAmt,
|
||||
uint getId,
|
||||
uint setIdAmount,
|
||||
uint setIdReward
|
||||
);
|
||||
|
||||
event LogClaimedReward(
|
||||
address indexed rewardToken,
|
||||
bytes32 indexed stakingType,
|
||||
uint256 rewardAmt,
|
||||
uint setId
|
||||
);
|
||||
|
||||
}
|
48
contracts/mainnet/connectors/erc20_staking/helpers.sol
Normal file
48
contracts/mainnet/connectors/erc20_staking/helpers.sol
Normal file
|
@ -0,0 +1,48 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
|
||||
import { DSMath } from "../../common/math.sol";
|
||||
import { Basic } from "../../common/basic.sol";
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { IStakingRewards, StakingERC20Mapping } from "./interface.sol";
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
||||
|
||||
/**
|
||||
* @dev Convert String to bytes32.
|
||||
*/
|
||||
function stringToBytes32(string memory str) internal pure returns (bytes32 result) {
|
||||
require(bytes(str).length != 0, "string-empty");
|
||||
// solium-disable-next-line security/no-inline-assembly
|
||||
assembly {
|
||||
result := mload(add(str, 32))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Get staking data
|
||||
*/
|
||||
function getStakingData(string memory stakingName)
|
||||
internal
|
||||
view
|
||||
returns (
|
||||
IStakingRewards stakingContract,
|
||||
TokenInterface stakingToken,
|
||||
TokenInterface rewardToken,
|
||||
bytes32 stakingType
|
||||
)
|
||||
{
|
||||
stakingType = stringToBytes32(stakingName);
|
||||
StakingERC20Mapping.StakingData memory stakingData = StakingERC20Mapping(getMappingAddr()).stakingMapping(stakingType);
|
||||
require(stakingData.stakingPool != address(0) && stakingData.stakingToken != address(0), "Wrong Staking Name");
|
||||
stakingContract = IStakingRewards(stakingData.stakingPool);
|
||||
stakingToken = TokenInterface(stakingData.stakingToken);
|
||||
rewardToken = TokenInterface(stakingData.rewardToken);
|
||||
}
|
||||
|
||||
function getMappingAddr() internal virtual view returns (address) {
|
||||
return 0xbE658233bA9990d86155b3902fd05a7AfC7eBdB5; // InstaMapping Address
|
||||
}
|
||||
|
||||
}
|
21
contracts/mainnet/connectors/erc20_staking/interface.sol
Normal file
21
contracts/mainnet/connectors/erc20_staking/interface.sol
Normal file
|
@ -0,0 +1,21 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
interface IStakingRewards {
|
||||
function stake(uint256 amount) external;
|
||||
function withdraw(uint256 amount) external;
|
||||
function getReward() external;
|
||||
function balanceOf(address) external view returns(uint);
|
||||
}
|
||||
|
||||
interface StakingERC20Mapping {
|
||||
|
||||
struct StakingData {
|
||||
address stakingPool;
|
||||
address stakingToken;
|
||||
address rewardToken;
|
||||
}
|
||||
|
||||
function stakingMapping(bytes32) external view returns(StakingData memory);
|
||||
|
||||
}
|
120
contracts/mainnet/connectors/erc20_staking/main.sol
Normal file
120
contracts/mainnet/connectors/erc20_staking/main.sol
Normal file
|
@ -0,0 +1,120 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/**
|
||||
* @title Token Staking.
|
||||
* @dev Stake ERC20 for earning rewards.
|
||||
*/
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { Stores } from "../../common/stores.sol";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
import { Events } from "./events.sol";
|
||||
import { IStakingRewards, StakingERC20Mapping } from "./interface.sol";
|
||||
|
||||
contract Main is Helpers, Events {
|
||||
|
||||
/**
|
||||
* @dev Deposit ERC20.
|
||||
* @notice Deposit Tokens to staking pool.
|
||||
* @param stakingPoolName staking pool name.
|
||||
* @param amt staking token amount.
|
||||
* @param getId ID to retrieve amount.
|
||||
* @param setId ID stores the amount of staked tokens.
|
||||
*/
|
||||
function deposit(
|
||||
string calldata stakingPoolName,
|
||||
uint amt,
|
||||
uint getId,
|
||||
uint setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _amt = getUint(getId, amt);
|
||||
(
|
||||
IStakingRewards stakingContract,
|
||||
TokenInterface stakingToken,
|
||||
,
|
||||
bytes32 stakingType
|
||||
) = getStakingData(stakingPoolName);
|
||||
|
||||
_amt = _amt == uint(-1) ? stakingToken.balanceOf(address(this)) : _amt;
|
||||
|
||||
stakingToken.approve(address(stakingContract), _amt);
|
||||
stakingContract.stake(_amt);
|
||||
|
||||
setUint(setId, _amt);
|
||||
_eventName = "LogDeposit(address,bytes32,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(address(stakingToken), stakingType, _amt, getId, setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Withdraw ERC20.
|
||||
* @notice Withdraw Tokens from the staking pool.
|
||||
* @param stakingPoolName staking pool name.
|
||||
* @param amt staking token amount.
|
||||
* @param getId ID to retrieve amount.
|
||||
* @param setIdAmount ID stores the amount of stake tokens withdrawn.
|
||||
* @param setIdReward ID stores the amount of reward tokens claimed.
|
||||
*/
|
||||
function withdraw(
|
||||
string calldata stakingPoolName,
|
||||
uint amt,
|
||||
uint getId,
|
||||
uint setIdAmount,
|
||||
uint setIdReward
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _amt = getUint(getId, amt);
|
||||
(
|
||||
IStakingRewards stakingContract,
|
||||
TokenInterface stakingToken,
|
||||
TokenInterface rewardToken,
|
||||
bytes32 stakingType
|
||||
) = getStakingData(stakingPoolName);
|
||||
|
||||
_amt = _amt == uint(-1) ? stakingContract.balanceOf(address(this)) : _amt;
|
||||
uint intialBal = rewardToken.balanceOf(address(this));
|
||||
stakingContract.withdraw(_amt);
|
||||
stakingContract.getReward();
|
||||
|
||||
uint rewardAmt = sub(rewardToken.balanceOf(address(this)), intialBal);
|
||||
|
||||
setUint(setIdAmount, _amt);
|
||||
setUint(setIdReward, rewardAmt);
|
||||
{
|
||||
_eventName = "LogWithdrawAndClaimedReward(address,bytes32,uint256,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(address(stakingToken), stakingType, _amt, rewardAmt, getId, setIdAmount, setIdReward);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Claim Reward.
|
||||
* @notice Claim Pending Rewards of tokens staked.
|
||||
* @param stakingPoolName staking pool name.
|
||||
* @param setId ID stores the amount of reward tokens claimed.
|
||||
*/
|
||||
function claimReward(
|
||||
string calldata stakingPoolName,
|
||||
uint setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
(
|
||||
IStakingRewards stakingContract,
|
||||
,
|
||||
TokenInterface rewardToken,
|
||||
bytes32 stakingType
|
||||
) = getStakingData(stakingPoolName);
|
||||
|
||||
uint intialBal = rewardToken.balanceOf(address(this));
|
||||
stakingContract.getReward();
|
||||
uint finalBal = rewardToken.balanceOf(address(this));
|
||||
|
||||
uint rewardAmt = sub(finalBal, intialBal);
|
||||
|
||||
setUint(setId, rewardAmt);
|
||||
_eventName = "LogClaimedReward(address,bytes32,uint256,uint256)";
|
||||
_eventParam = abi.encode(address(rewardToken), stakingType, rewardAmt, setId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
contract connectV2StakeERC20 is Main {
|
||||
string public constant name = "Stake-ERC20-v1.0";
|
||||
}
|
34
contracts/mainnet/connectors/guniswap_v3_erc20/events.sol
Normal file
34
contracts/mainnet/connectors/guniswap_v3_erc20/events.sol
Normal file
|
@ -0,0 +1,34 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
|
||||
event LogDepositLiquidity(
|
||||
address indexed pool,
|
||||
uint256 amtA,
|
||||
uint256 amtB,
|
||||
uint256 mintAmount,
|
||||
uint256[] getIds,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogWithdrawLiquidity(
|
||||
address indexed pool,
|
||||
uint256 amountA,
|
||||
uint256 amountB,
|
||||
uint256 burnAmount,
|
||||
uint256 getId,
|
||||
uint256[] setIds
|
||||
);
|
||||
|
||||
event LogSwapAndDepositLiquidity(
|
||||
address indexed pool,
|
||||
uint256 amtA,
|
||||
uint256 amtB,
|
||||
uint256 mintAmount,
|
||||
bool zeroForOne,
|
||||
uint swapAmount,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
}
|
32
contracts/mainnet/connectors/guniswap_v3_erc20/helpers.sol
Normal file
32
contracts/mainnet/connectors/guniswap_v3_erc20/helpers.sol
Normal file
|
@ -0,0 +1,32 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import { DSMath } from "../../common/math.sol";
|
||||
import { Basic } from "../../common/basic.sol";
|
||||
|
||||
import { IGUniRouter, IGUniPool, IERC20 } from "./interface.sol";
|
||||
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
||||
|
||||
IGUniRouter public constant gUniRouter = IGUniRouter(0x8CA6fa325bc32f86a12cC4964Edf1f71655007A7);
|
||||
|
||||
struct DepositAndSwap {
|
||||
IGUniPool poolContract;
|
||||
IERC20 _token0;
|
||||
IERC20 _token1;
|
||||
uint amount0;
|
||||
uint amount1;
|
||||
uint mintAmount;
|
||||
}
|
||||
|
||||
struct Deposit {
|
||||
IGUniPool poolContract;
|
||||
IERC20 _token0;
|
||||
IERC20 _token1;
|
||||
uint amount0In;
|
||||
uint amount1In;
|
||||
uint mintAmount;
|
||||
}
|
||||
|
||||
}
|
120
contracts/mainnet/connectors/guniswap_v3_erc20/interface.sol
Normal file
120
contracts/mainnet/connectors/guniswap_v3_erc20/interface.sol
Normal file
|
@ -0,0 +1,120 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
|
||||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
interface IGUniPool {
|
||||
|
||||
function token0() external view returns (IERC20);
|
||||
|
||||
function token1() external view returns (IERC20);
|
||||
|
||||
function mint(
|
||||
uint256 amount,
|
||||
address receiver
|
||||
) external
|
||||
returns (
|
||||
uint256 amount0,
|
||||
uint256 amount1,
|
||||
uint256 mintAmount
|
||||
);
|
||||
|
||||
function burn(
|
||||
uint256 _burnAmount,
|
||||
address _receiver
|
||||
) external
|
||||
returns (
|
||||
uint256 amount0,
|
||||
uint256 amount1,
|
||||
uint128 liquidityBurned
|
||||
);
|
||||
|
||||
function getMintAmounts(
|
||||
uint256 amount0Max,
|
||||
uint256 amount1Max
|
||||
) external view
|
||||
returns (
|
||||
uint256 amount0,
|
||||
uint256 amount1,
|
||||
uint256 mintAmount
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
interface IGUniRouter {
|
||||
function rebalanceAndAddLiquidity(
|
||||
IGUniPool pool,
|
||||
uint256 amount0In,
|
||||
uint256 amount1In,
|
||||
bool zeroForOne,
|
||||
uint256 swapAmount,
|
||||
uint160 swapThreshold,
|
||||
uint256 amount0Min,
|
||||
uint256 amount1Min,
|
||||
address receiver
|
||||
)
|
||||
external
|
||||
returns (
|
||||
uint256 amount0,
|
||||
uint256 amount1,
|
||||
uint256 mintAmount
|
||||
);
|
||||
|
||||
function rebalanceAndAddLiquidityETH(
|
||||
IGUniPool pool,
|
||||
uint256 amount0In,
|
||||
uint256 amount1In,
|
||||
bool zeroForOne,
|
||||
uint256 swapAmount,
|
||||
uint160 swapThreshold,
|
||||
uint256 amount0Min,
|
||||
uint256 amount1Min,
|
||||
address receiver
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (
|
||||
uint256 amount0,
|
||||
uint256 amount1,
|
||||
uint256 mintAmount
|
||||
);
|
||||
|
||||
function removeLiquidity(
|
||||
IGUniPool pool,
|
||||
uint256 burnAmount,
|
||||
uint256 amount0Min,
|
||||
uint256 amount1Min,
|
||||
address receiver
|
||||
)
|
||||
external
|
||||
returns (
|
||||
uint256 amount0,
|
||||
uint256 amount1,
|
||||
uint128 liquidityBurned
|
||||
);
|
||||
|
||||
function removeLiquidityETH(
|
||||
IGUniPool pool,
|
||||
uint256 burnAmount,
|
||||
uint256 amount0Min,
|
||||
uint256 amount1Min,
|
||||
address payable receiver
|
||||
)
|
||||
external
|
||||
returns (
|
||||
uint256 amount0,
|
||||
uint256 amount1,
|
||||
uint128 liquidityBurned
|
||||
);
|
||||
}
|
||||
|
||||
interface TokenInterface {
|
||||
function approve(address, uint256) external;
|
||||
function transfer(address, uint) external;
|
||||
function transferFrom(address, address, uint) external;
|
||||
function deposit() external payable;
|
||||
function withdraw(uint) external;
|
||||
function balanceOf(address) external view returns (uint);
|
||||
function decimals() external view returns (uint);
|
||||
}
|
220
contracts/mainnet/connectors/guniswap_v3_erc20/main.sol
Normal file
220
contracts/mainnet/connectors/guniswap_v3_erc20/main.sol
Normal file
|
@ -0,0 +1,220 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
/**
|
||||
* @title G-Uniswap V3 ERC20 Wrapper.
|
||||
* @dev G-Uniswap V3 Wrapper to deposit and withdraw.
|
||||
*/
|
||||
|
||||
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { IGUniPool, IERC20 } from "./interface.sol";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
import { Events } from "./events.sol";
|
||||
|
||||
abstract contract UniswapV3Resolver is Events, Helpers {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
/**
|
||||
* @dev Deposit Liquidity.
|
||||
* @notice Deposit Liquidity to Gelato Uniswap V3 pool.
|
||||
* @param pool The address of pool.
|
||||
* @param amt0Max Amount0 Max amount
|
||||
* @param amt1Max Amount1 Max amount
|
||||
* @param slippage use to calculate minimum deposit. 100% = 1e18
|
||||
* @param getIds Array of IDs to retrieve amounts.
|
||||
* @param setId ID stores the amount of pools tokens received.
|
||||
*/
|
||||
function deposit(
|
||||
address pool,
|
||||
uint256 amt0Max,
|
||||
uint256 amt1Max,
|
||||
uint slippage,
|
||||
uint256[] calldata getIds,
|
||||
uint256 setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
|
||||
amt0Max = getUint(getIds[0], amt0Max);
|
||||
amt1Max = getUint(getIds[1], amt1Max);
|
||||
|
||||
Deposit memory depositData;
|
||||
depositData.poolContract = IGUniPool(pool);
|
||||
|
||||
(depositData.amount0In, depositData.amount1In, depositData.mintAmount) =
|
||||
depositData.poolContract.getMintAmounts(amt0Max, amt1Max);
|
||||
|
||||
uint amt0Min = wmul(amt0Max, slippage);
|
||||
uint amt1Min = wmul(amt1Max, slippage);
|
||||
|
||||
require(
|
||||
depositData.amount0In >= amt0Min && depositData.amount1In >= amt1Min,
|
||||
"below min amounts"
|
||||
);
|
||||
|
||||
if (depositData.amount0In > 0) {
|
||||
IERC20 _token0 = depositData.poolContract.token0();
|
||||
convertEthToWeth(address(_token0) == wethAddr, TokenInterface(address(_token0)), depositData.amount0In);
|
||||
_token0.safeApprove(address(pool), depositData.amount0In);
|
||||
}
|
||||
if (depositData.amount1In > 0) {
|
||||
IERC20 _token1 = depositData.poolContract.token1();
|
||||
convertEthToWeth(address(_token1) == wethAddr, TokenInterface(address(_token1)), depositData.amount1In);
|
||||
_token1.safeApprove(address(pool), depositData.amount1In);
|
||||
}
|
||||
|
||||
(uint amount0, uint amount1,) = depositData.poolContract.mint(depositData.mintAmount, address(this));
|
||||
|
||||
require(
|
||||
amount0 == depositData.amount0In &&
|
||||
amount1 == depositData.amount1In, "unexpected amounts deposited");
|
||||
|
||||
setUint(setId, depositData.mintAmount);
|
||||
|
||||
_eventName = "LogDepositLiquidity(address,uint256,uint256,uint256,uint256[],uint256)";
|
||||
_eventParam = abi.encode(pool, amount0, amount1, depositData.mintAmount, getIds, setId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dev Withdraw Liquidity.
|
||||
* @notice Withdraw Liquidity from Gelato Uniswap V3 pool.
|
||||
* @param pool The address of pool.
|
||||
* @param liqAmt Amount0 Max amount
|
||||
* @param minAmtA Min AmountA amount
|
||||
* @param minAmtB Min AmountB amount
|
||||
* @param getId ID to retrieve liqAmt.
|
||||
* @param setIds Array of IDs tp stores the amounts of pools tokens received.
|
||||
*/
|
||||
function withdraw(
|
||||
address pool,
|
||||
uint256 liqAmt,
|
||||
uint256 minAmtA,
|
||||
uint256 minAmtB,
|
||||
uint256 getId,
|
||||
uint256[] calldata setIds
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
|
||||
liqAmt = getUint(getId, liqAmt);
|
||||
|
||||
IGUniPool poolContract = IGUniPool(pool);
|
||||
|
||||
(uint amount0, uint amount1, uint128 liquidityBurned) = poolContract.burn(liqAmt, address(this));
|
||||
|
||||
if (amount0 > 0) {
|
||||
IERC20 _token0 = poolContract.token0();
|
||||
convertWethToEth(address(_token0) == wethAddr, TokenInterface(address(_token0)), amount0);
|
||||
}
|
||||
|
||||
if (amount1 > 0) {
|
||||
IERC20 _token1 = poolContract.token1();
|
||||
convertWethToEth(address(_token1) == wethAddr, TokenInterface(address(_token1)), amount1);
|
||||
}
|
||||
|
||||
require(amount0 >= minAmtA && amount1 >= minAmtB, "received below minimum");
|
||||
|
||||
setUint(setIds[0], amount0);
|
||||
setUint(setIds[1], amount1);
|
||||
|
||||
_eventName = "LogWithdrawLiquidity(address,uint256,uint256,uint256,uint256,uint256[])";
|
||||
_eventParam = abi.encode(pool, amount0, amount1, uint256(liquidityBurned), getId, setIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Swap & Deposit Liquidity.
|
||||
* @notice Withdraw Liquidity to Gelato Uniswap V3 pool.
|
||||
* @param pool The address of pool.
|
||||
* @param amount0In amount of token0 to deposit.
|
||||
* @param amount1In amount of token1 to deposit.
|
||||
* @param zeroForOne Swap excess of one token to deposit in equal ratio.
|
||||
* @param swapAmount Amount of tokens to swap
|
||||
* @param swapThreshold Slippage that the swap could take.
|
||||
* @param getId Not used anywhere here.
|
||||
* @param setId Set the amount of tokens minted.
|
||||
*/
|
||||
function swapAndDeposit(
|
||||
address pool,
|
||||
uint256 amount0In,
|
||||
uint256 amount1In,
|
||||
bool zeroForOne,
|
||||
uint256 swapAmount,
|
||||
uint160 swapThreshold,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
DepositAndSwap memory depositAndSwap;
|
||||
depositAndSwap.poolContract = IGUniPool(pool);
|
||||
depositAndSwap._token0 = depositAndSwap.poolContract.token0();
|
||||
depositAndSwap._token1 = depositAndSwap.poolContract.token1();
|
||||
|
||||
depositAndSwap.amount0;
|
||||
depositAndSwap.amount1;
|
||||
depositAndSwap.mintAmount;
|
||||
|
||||
if (address(depositAndSwap._token0) == wethAddr) {
|
||||
depositAndSwap._token1.approve(address(gUniRouter), amount1In);
|
||||
|
||||
(depositAndSwap.amount0, depositAndSwap.amount1, depositAndSwap.mintAmount) =
|
||||
gUniRouter.rebalanceAndAddLiquidityETH{value: amount0In}(
|
||||
depositAndSwap.poolContract,
|
||||
amount0In,
|
||||
amount1In,
|
||||
zeroForOne,
|
||||
swapAmount,
|
||||
swapThreshold,
|
||||
0,
|
||||
0,
|
||||
address(this)
|
||||
);
|
||||
} else if (address(depositAndSwap._token1) == wethAddr) {
|
||||
depositAndSwap._token0.approve(address(gUniRouter), amount0In);
|
||||
|
||||
(depositAndSwap.amount0, depositAndSwap.amount1,depositAndSwap. mintAmount) =
|
||||
gUniRouter.rebalanceAndAddLiquidityETH{value: amount1In}(
|
||||
depositAndSwap.poolContract,
|
||||
amount0In,
|
||||
amount1In,
|
||||
zeroForOne,
|
||||
swapAmount,
|
||||
swapThreshold,
|
||||
0,
|
||||
0,
|
||||
address(this)
|
||||
);
|
||||
} else {
|
||||
depositAndSwap._token0.approve(address(gUniRouter), amount0In);
|
||||
depositAndSwap._token1.approve(address(gUniRouter), amount1In);
|
||||
(depositAndSwap.amount0, depositAndSwap.amount1, depositAndSwap.mintAmount) =
|
||||
gUniRouter.rebalanceAndAddLiquidity(
|
||||
depositAndSwap.poolContract,
|
||||
amount0In,
|
||||
amount1In,
|
||||
zeroForOne,
|
||||
swapAmount,
|
||||
swapThreshold,
|
||||
0,
|
||||
0,
|
||||
address(this)
|
||||
);
|
||||
}
|
||||
|
||||
setUint(setId, depositAndSwap.mintAmount);
|
||||
|
||||
_eventName = "LogSwapAndDepositLiquidity(address,uint256,uint256,uint256,bool,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
pool,
|
||||
depositAndSwap.amount0,
|
||||
depositAndSwap.amount1,
|
||||
depositAndSwap.mintAmount,
|
||||
zeroForOne,
|
||||
swapAmount,
|
||||
getId,
|
||||
setId
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
contract ConnectV2GUniswapV3ERC20 is UniswapV3Resolver {
|
||||
string public constant name = "G-Uniswap-v3-ERC20-v1.0";
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
|
||||
event LogDeposit(
|
||||
address indexed stakingToken,
|
||||
uint256 amount,
|
||||
uint getId,
|
||||
uint setId
|
||||
);
|
||||
|
||||
event LogWithdrawAndClaimedReward(
|
||||
address indexed stakingToken,
|
||||
uint256 amount,
|
||||
uint256 rewardAmt,
|
||||
uint getId,
|
||||
uint setIdAmount,
|
||||
uint setIdReward
|
||||
);
|
||||
|
||||
event LogClaimedReward(
|
||||
address indexed rewardToken,
|
||||
uint256 rewardAmt,
|
||||
uint setId
|
||||
);
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
|
||||
import { DSMath } from "../../common/math.sol";
|
||||
import { Basic } from "../../common/basic.sol";
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { IStakingRewards, IStakingRewardsFactory, IGUniPoolResolver } from "./interface.sol";
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
||||
|
||||
IGUniPoolResolver constant internal guniResolver =
|
||||
IGUniPoolResolver(0x729BF02a9A786529Fc80498f8fd0051116061B13);
|
||||
|
||||
TokenInterface constant internal rewardToken = TokenInterface(0x6f40d4A6237C257fff2dB00FA0510DeEECd303eb);
|
||||
|
||||
function getStakingContract(address stakingToken) internal view returns (address) {
|
||||
IStakingRewardsFactory.StakingRewardsInfo memory stakingRewardsInfo =
|
||||
guniResolver.getStakingFactory().stakingRewardsInfoByStakingToken(stakingToken);
|
||||
|
||||
return stakingRewardsInfo.stakingRewards;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
interface IStakingRewards {
|
||||
function stake(uint256 amount) external;
|
||||
function withdraw(uint256 amount) external;
|
||||
function getReward() external;
|
||||
function balanceOf(address) external view returns(uint);
|
||||
}
|
||||
|
||||
interface IStakingRewardsFactory {
|
||||
|
||||
struct StakingRewardsInfo {
|
||||
address stakingRewards;
|
||||
uint rewardAmount;
|
||||
}
|
||||
|
||||
function stakingRewardsInfoByStakingToken(address) external view returns(StakingRewardsInfo memory);
|
||||
|
||||
}
|
||||
|
||||
interface IGUniPoolResolver {
|
||||
|
||||
function getStakingFactory() external view returns(IStakingRewardsFactory);
|
||||
|
||||
}
|
108
contracts/mainnet/connectors/guniswap_v3_erc20_staking/main.sol
Normal file
108
contracts/mainnet/connectors/guniswap_v3_erc20_staking/main.sol
Normal file
|
@ -0,0 +1,108 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/**
|
||||
* @title G-UNI Staking.
|
||||
* @dev Stake G-UNI for earning rewards.
|
||||
*/
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { Stores } from "../../common/stores.sol";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
import { Events } from "./events.sol";
|
||||
import { IStakingRewards, IStakingRewardsFactory } from "./interface.sol";
|
||||
|
||||
contract Main is Helpers, Events {
|
||||
|
||||
/**
|
||||
* @dev Deposit ERC20.
|
||||
* @notice Deposit Tokens to staking pool.
|
||||
* @param stakingToken staking token address.
|
||||
* @param amt staking token amount.
|
||||
* @param getId ID to retrieve amount.
|
||||
* @param setId ID stores the amount of staked tokens.
|
||||
*/
|
||||
function deposit(
|
||||
address stakingToken,
|
||||
uint amt,
|
||||
uint getId,
|
||||
uint setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _amt = getUint(getId, amt);
|
||||
|
||||
IStakingRewards stakingContract = IStakingRewards(getStakingContract(stakingToken));
|
||||
TokenInterface stakingTokenContract = TokenInterface(stakingToken);
|
||||
|
||||
_amt = _amt == uint(-1) ? stakingTokenContract.balanceOf(address(this)) : _amt;
|
||||
|
||||
stakingTokenContract.approve(address(stakingContract), _amt);
|
||||
stakingContract.stake(_amt);
|
||||
|
||||
setUint(setId, _amt);
|
||||
_eventName = "LogDeposit(address,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(address(stakingToken), _amt, getId, setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Withdraw ERC20.
|
||||
* @notice Withdraw Tokens from the staking pool.
|
||||
* @param stakingToken staking token address.
|
||||
* @param amt staking token amount.
|
||||
* @param getId ID to retrieve amount.
|
||||
* @param setIdAmount ID stores the amount of stake tokens withdrawn.
|
||||
* @param setIdReward ID stores the amount of reward tokens claimed.
|
||||
*/
|
||||
function withdraw(
|
||||
address stakingToken,
|
||||
uint amt,
|
||||
uint getId,
|
||||
uint setIdAmount,
|
||||
uint setIdReward
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _amt = getUint(getId, amt);
|
||||
|
||||
IStakingRewards stakingContract = IStakingRewards(getStakingContract(stakingToken));
|
||||
|
||||
_amt = _amt == uint(-1) ? stakingContract.balanceOf(address(this)) : _amt;
|
||||
uint intialBal = rewardToken.balanceOf(address(this));
|
||||
stakingContract.withdraw(_amt);
|
||||
stakingContract.getReward();
|
||||
|
||||
uint rewardAmt = sub(rewardToken.balanceOf(address(this)), intialBal);
|
||||
|
||||
setUint(setIdAmount, _amt);
|
||||
setUint(setIdReward, rewardAmt);
|
||||
{
|
||||
_eventName = "LogWithdrawAndClaimedReward(address,uint256,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(address(stakingToken), _amt, rewardAmt, getId, setIdAmount, setIdReward);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Claim Reward.
|
||||
* @notice Claim Pending Rewards of tokens staked.
|
||||
* @param stakingToken staking token address.
|
||||
* @param setId ID stores the amount of reward tokens claimed.
|
||||
*/
|
||||
function claimReward(
|
||||
address stakingToken,
|
||||
uint setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
IStakingRewards stakingContract = IStakingRewards(getStakingContract(stakingToken));
|
||||
|
||||
uint intialBal = rewardToken.balanceOf(address(this));
|
||||
stakingContract.getReward();
|
||||
uint finalBal = rewardToken.balanceOf(address(this));
|
||||
|
||||
uint rewardAmt = sub(finalBal, intialBal);
|
||||
|
||||
setUint(setId, rewardAmt);
|
||||
_eventName = "LogClaimedReward(address,uint256,uint256)";
|
||||
_eventParam = abi.encode(address(rewardToken), rewardAmt, setId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
contract connectV2StakeGUNI is Main {
|
||||
string public constant name = "Stake-G-UNI-v1.0";
|
||||
}
|
|
@ -43,7 +43,7 @@ abstract contract Helpers is DSMath, Basic {
|
|||
* @dev Gem Join address is ETH type collateral.
|
||||
*/
|
||||
function isEth(address tknAddr) internal pure returns (bool) {
|
||||
return tknAddr == ethAddr ? true : false;
|
||||
return tknAddr == wethAddr ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,7 +5,7 @@ pragma solidity ^0.7.0;
|
|||
* @dev Collateralized Borrowing.
|
||||
*/
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { TokenInterface, AccountInterface } from "../../common/interfaces.sol";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
import { Events } from "./events.sol";
|
||||
import { VatLike, TokenJoinInterface } from "./interface.sol";
|
||||
|
@ -44,6 +44,29 @@ abstract contract MakerResolver is Helpers, Events {
|
|||
_eventParam = abi.encode(_vault, ilk);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfer Vault
|
||||
* @notice Transfer a MakerDAO Vault to "nextOwner"
|
||||
* @param vault Vault ID to close.
|
||||
* @param nextOwner Address of the next owner of the vault.
|
||||
*/
|
||||
function transfer(
|
||||
uint vault,
|
||||
address nextOwner
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
require(AccountInterface(address(this)).isAuth(nextOwner), "nextOwner-is-not-auth");
|
||||
|
||||
uint256 _vault = getVault(vault);
|
||||
(bytes32 ilk,) = getVaultData(_vault);
|
||||
|
||||
require(managerContract.owns(_vault) == address(this), "not-owner");
|
||||
|
||||
managerContract.give(_vault, nextOwner);
|
||||
|
||||
_eventName = "LogTransfer(uint256,bytes32,address)";
|
||||
_eventParam = abi.encode(_vault, ilk, nextOwner);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Deposit ETH/ERC20_Token Collateral.
|
||||
* @notice Deposit collateral to a MakerDAO vault
|
||||
|
@ -495,6 +518,6 @@ abstract contract MakerResolver is Helpers, Events {
|
|||
}
|
||||
}
|
||||
|
||||
contract ConnectV2Maker is MakerResolver {
|
||||
string public constant name = "MakerDao-v1";
|
||||
contract ConnectV2MakerDAO is MakerResolver {
|
||||
string public constant name = "MakerDAO-v1.1";
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ pragma solidity ^0.7.0;
|
|||
|
||||
import { DSMath } from "../../common/math.sol";
|
||||
import { Basic } from "../../common/basic.sol";
|
||||
import { RootChainManagerInterface } from "./interface.sol";
|
||||
import { RootChainManagerInterface, DepositManagerProxyInterface } from "./interface.sol";
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
||||
/**
|
||||
|
@ -14,4 +14,9 @@ abstract contract Helpers is DSMath, Basic {
|
|||
* @dev Polygon POS Bridge Manager
|
||||
*/
|
||||
RootChainManagerInterface internal constant migrator = RootChainManagerInterface(0xA0c68C638235ee32657e8f720a23ceC1bFc77C77);
|
||||
|
||||
/**
|
||||
* @dev Polygon Plasma Bridge Manager
|
||||
*/
|
||||
DepositManagerProxyInterface internal constant migratorPlasma = DepositManagerProxyInterface(0x401F6c983eA34274ec46f84D70b31C151321188b);
|
||||
}
|
|
@ -2,10 +2,19 @@ pragma solidity ^0.7.0;
|
|||
|
||||
interface RootChainManagerInterface {
|
||||
function depositEtherFor(address user) external payable;
|
||||
function rootToChildToken(address user) external view returns(address);
|
||||
function depositFor(
|
||||
address user,
|
||||
address rootToken,
|
||||
bytes calldata depositData
|
||||
) external;
|
||||
function exit(bytes calldata inputData) external;
|
||||
}
|
||||
|
||||
interface DepositManagerProxyInterface {
|
||||
function depositERC20ForUser(
|
||||
address _token,
|
||||
address _user,
|
||||
uint256 _amount
|
||||
) external;
|
||||
}
|
|
@ -35,8 +35,13 @@ abstract contract PolygonBridgeResolver is Events, Helpers {
|
|||
} else {
|
||||
TokenInterface _token = TokenInterface(token);
|
||||
_amt = _amt == uint(-1) ? _token.balanceOf(address(this)) : _amt;
|
||||
_token.approve(erc20Predicate, _amt);
|
||||
migrator.depositFor(targetDsa, token, abi.encode(_amt));
|
||||
if (migrator.rootToChildToken(token) != address(0)) {
|
||||
_token.approve(erc20Predicate, _amt);
|
||||
migrator.depositFor(targetDsa, token, abi.encode(_amt));
|
||||
} else {
|
||||
_token.approve(address(migratorPlasma), _amt);
|
||||
migratorPlasma.depositERC20ForUser(token, targetDsa, _amt);
|
||||
}
|
||||
}
|
||||
|
||||
setUint(setId, _amt);
|
||||
|
@ -47,5 +52,5 @@ abstract contract PolygonBridgeResolver is Events, Helpers {
|
|||
}
|
||||
|
||||
contract ConnectV2PolygonBridge is PolygonBridgeResolver {
|
||||
string public constant name = "Polygon-Bridge-v1";
|
||||
string public constant name = "Polygon-Bridge-v1.1";
|
||||
}
|
0
contracts/mainnet/connectors/refinance/events.sol
Normal file
0
contracts/mainnet/connectors/refinance/events.sol
Normal file
155
contracts/mainnet/connectors/refinance/helpers.sol
Normal file
155
contracts/mainnet/connectors/refinance/helpers.sol
Normal file
|
@ -0,0 +1,155 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import { Basic } from "../../common/basic.sol";
|
||||
|
||||
|
||||
import {
|
||||
AaveV1ProviderInterface,
|
||||
AaveV1Interface,
|
||||
AaveV2LendingPoolProviderInterface,
|
||||
AaveV2DataProviderInterface,
|
||||
AaveV2Interface,
|
||||
ComptrollerInterface,
|
||||
CTokenInterface,
|
||||
CompoundMappingInterface
|
||||
} from "./interfaces.sol";
|
||||
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
|
||||
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
|
||||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
|
||||
contract Helpers is Basic {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
enum Protocol {
|
||||
Aave,
|
||||
AaveV2,
|
||||
Compound
|
||||
}
|
||||
|
||||
address payable constant feeCollector = 0xb1DC62EC38E6E3857a887210C38418E4A17Da5B2;
|
||||
|
||||
/**
|
||||
* @dev Return InstaDApp Mapping Address
|
||||
*/
|
||||
address constant internal getMappingAddr = 0xA8F9D4aA7319C54C04404765117ddBf9448E2082; // CompoundMapping Address
|
||||
|
||||
/**
|
||||
* @dev Return Compound Comptroller Address
|
||||
*/
|
||||
address constant internal getComptrollerAddress = 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B; // CompoundMapping Address
|
||||
|
||||
/**
|
||||
* @dev get Aave Provider
|
||||
*/
|
||||
AaveV1ProviderInterface constant internal getAaveProvider =
|
||||
AaveV1ProviderInterface(0x24a42fD28C976A61Df5D00D0599C34c4f90748c8);
|
||||
|
||||
/**
|
||||
* @dev get Aave Lending Pool Provider
|
||||
*/
|
||||
AaveV2LendingPoolProviderInterface constant internal getAaveV2Provider =
|
||||
AaveV2LendingPoolProviderInterface(0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5);
|
||||
|
||||
/**
|
||||
* @dev get Aave Protocol Data Provider
|
||||
*/
|
||||
AaveV2DataProviderInterface constant internal getAaveV2DataProvider =
|
||||
AaveV2DataProviderInterface(0x057835Ad21a177dbdd3090bB1CAE03EaCF78Fc6d);
|
||||
|
||||
/**
|
||||
* @dev get Referral Code
|
||||
*/
|
||||
uint16 constant internal getReferralCode = 3228;
|
||||
}
|
||||
|
||||
contract protocolHelpers is Helpers {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
function getWithdrawBalance(AaveV1Interface aave, address token) internal view returns (uint bal) {
|
||||
(bal, , , , , , , , , ) = aave.getUserReserveData(token, address(this));
|
||||
}
|
||||
|
||||
function getPaybackBalance(AaveV1Interface aave, address token) internal view returns (uint bal, uint fee) {
|
||||
(, bal, , , , , fee, , , ) = aave.getUserReserveData(token, address(this));
|
||||
}
|
||||
|
||||
function getTotalBorrowBalance(AaveV1Interface aave, address token) internal view returns (uint amt) {
|
||||
(, uint bal, , , , , uint fee, , , ) = aave.getUserReserveData(token, address(this));
|
||||
amt = add(bal, fee);
|
||||
}
|
||||
|
||||
function getWithdrawBalanceV2(AaveV2DataProviderInterface aaveData, address token) internal view returns (uint bal) {
|
||||
(bal, , , , , , , , ) = aaveData.getUserReserveData(token, address(this));
|
||||
}
|
||||
|
||||
function getPaybackBalanceV2(AaveV2DataProviderInterface aaveData, address token, uint rateMode) internal view returns (uint bal) {
|
||||
if (rateMode == 1) {
|
||||
(, bal, , , , , , , ) = aaveData.getUserReserveData(token, address(this));
|
||||
} else {
|
||||
(, , bal, , , , , , ) = aaveData.getUserReserveData(token, address(this));
|
||||
}
|
||||
}
|
||||
|
||||
function getIsColl(AaveV1Interface aave, address token) internal view returns (bool isCol) {
|
||||
(, , , , , , , , , isCol) = aave.getUserReserveData(token, address(this));
|
||||
}
|
||||
|
||||
function getIsCollV2(AaveV2DataProviderInterface aaveData, address token) internal view returns (bool isCol) {
|
||||
(, , , , , , , , isCol) = aaveData.getUserReserveData(token, address(this));
|
||||
}
|
||||
|
||||
function getMaxBorrow(Protocol target, address token, CTokenInterface ctoken, uint rateMode) internal returns (uint amt) {
|
||||
AaveV1Interface aaveV1 = AaveV1Interface(getAaveProvider.getLendingPool());
|
||||
AaveV2DataProviderInterface aaveData = getAaveV2DataProvider;
|
||||
|
||||
if (target == Protocol.Aave) {
|
||||
(uint _amt, uint _fee) = getPaybackBalance(aaveV1, token);
|
||||
amt = _amt + _fee;
|
||||
} else if (target == Protocol.AaveV2) {
|
||||
amt = getPaybackBalanceV2(aaveData, token, rateMode);
|
||||
} else if (target == Protocol.Compound) {
|
||||
amt = ctoken.borrowBalanceCurrent(address(this));
|
||||
}
|
||||
}
|
||||
|
||||
function transferFees(address token, uint feeAmt) internal {
|
||||
if (feeAmt > 0) {
|
||||
if (token == ethAddr) {
|
||||
feeCollector.transfer(feeAmt);
|
||||
} else {
|
||||
IERC20(token).safeTransfer(feeCollector, feeAmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateFee(uint256 amount, uint256 fee, bool toAdd) internal pure returns(uint feeAmount, uint _amount){
|
||||
feeAmount = wmul(amount, fee);
|
||||
_amount = toAdd ? add(amount, feeAmount) : sub(amount, feeAmount);
|
||||
}
|
||||
|
||||
function getTokenInterfaces(uint length, address[] memory tokens) internal pure returns (TokenInterface[] memory) {
|
||||
TokenInterface[] memory _tokens = new TokenInterface[](length);
|
||||
for (uint i = 0; i < length; i++) {
|
||||
if (tokens[i] == ethAddr) {
|
||||
_tokens[i] = TokenInterface(wethAddr);
|
||||
} else {
|
||||
_tokens[i] = TokenInterface(tokens[i]);
|
||||
}
|
||||
}
|
||||
return _tokens;
|
||||
}
|
||||
|
||||
function getCtokenInterfaces(uint length, string[] memory tokenIds) internal view returns (CTokenInterface[] memory) {
|
||||
CTokenInterface[] memory _ctokens = new CTokenInterface[](length);
|
||||
for (uint i = 0; i < length; i++) {
|
||||
(address token, address cToken) = CompoundMappingInterface(getMappingAddr).getMapping(tokenIds[i]);
|
||||
require(token != address(0) && cToken != address(0), "invalid token/ctoken address");
|
||||
_ctokens[i] = CTokenInterface(cToken);
|
||||
}
|
||||
return _ctokens;
|
||||
}
|
||||
}
|
202
contracts/mainnet/connectors/refinance/helpers/aaveV1.sol
Normal file
202
contracts/mainnet/connectors/refinance/helpers/aaveV1.sol
Normal file
|
@ -0,0 +1,202 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import { protocolHelpers } from "../helpers.sol";
|
||||
|
||||
import {
|
||||
AaveV1ProviderInterface,
|
||||
AaveV1Interface,
|
||||
AaveV1CoreInterface,
|
||||
ATokenV1Interface,
|
||||
CTokenInterface
|
||||
// AaveV2LendingPoolProviderInterface,
|
||||
// AaveV2DataProviderInterface,
|
||||
// AaveV2Interface,
|
||||
} from "../interfaces.sol";
|
||||
|
||||
import { TokenInterface } from "../../../common/interfaces.sol";
|
||||
|
||||
contract AaveV1Helpers is protocolHelpers {
|
||||
|
||||
struct AaveV1BorrowData {
|
||||
AaveV1Interface aave;
|
||||
uint length;
|
||||
uint fee;
|
||||
Protocol target;
|
||||
TokenInterface[] tokens;
|
||||
CTokenInterface[] ctokens;
|
||||
uint[] amts;
|
||||
uint[] borrowRateModes;
|
||||
uint[] paybackRateModes;
|
||||
}
|
||||
|
||||
struct AaveV1DepositData {
|
||||
AaveV1Interface aave;
|
||||
AaveV1CoreInterface aaveCore;
|
||||
uint length;
|
||||
uint fee;
|
||||
TokenInterface[] tokens;
|
||||
uint[] amts;
|
||||
}
|
||||
|
||||
function _aaveV1BorrowOne(
|
||||
AaveV1Interface aave,
|
||||
uint fee,
|
||||
Protocol target,
|
||||
TokenInterface token,
|
||||
CTokenInterface ctoken,
|
||||
uint amt,
|
||||
uint borrowRateMode,
|
||||
uint paybackRateMode
|
||||
) internal returns (uint) {
|
||||
if (amt > 0) {
|
||||
|
||||
address _token = address(token) == wethAddr ? ethAddr : address(token);
|
||||
|
||||
if (amt == uint(-1)) {
|
||||
amt = getMaxBorrow(target, address(token), ctoken, paybackRateMode);
|
||||
}
|
||||
|
||||
(uint feeAmt, uint _amt) = calculateFee(amt, fee, true);
|
||||
|
||||
aave.borrow(_token, _amt, borrowRateMode, getReferralCode);
|
||||
transferFees(_token, feeAmt);
|
||||
}
|
||||
return amt;
|
||||
}
|
||||
|
||||
function _aaveV1Borrow(
|
||||
AaveV1BorrowData memory data
|
||||
) internal returns (uint[] memory) {
|
||||
uint[] memory finalAmts = new uint[](data.length);
|
||||
for (uint i = 0; i < data.length; i++) {
|
||||
finalAmts[i] = _aaveV1BorrowOne(
|
||||
data.aave,
|
||||
data.fee,
|
||||
data.target,
|
||||
data.tokens[i],
|
||||
data.ctokens[i],
|
||||
data.amts[i],
|
||||
data.borrowRateModes[i],
|
||||
data.paybackRateModes[i]
|
||||
);
|
||||
}
|
||||
return finalAmts;
|
||||
}
|
||||
|
||||
function _aaveV1DepositOne(
|
||||
AaveV1Interface aave,
|
||||
AaveV1CoreInterface aaveCore,
|
||||
uint fee,
|
||||
TokenInterface token,
|
||||
uint amt
|
||||
) internal {
|
||||
if (amt > 0) {
|
||||
uint ethAmt;
|
||||
(uint feeAmt, uint _amt) = calculateFee(amt, fee, false);
|
||||
|
||||
bool isEth = address(token) == wethAddr;
|
||||
|
||||
address _token = isEth ? ethAddr : address(token);
|
||||
|
||||
if (isEth) {
|
||||
ethAmt = _amt;
|
||||
} else {
|
||||
token.approve(address(aaveCore), _amt);
|
||||
}
|
||||
|
||||
transferFees(_token, feeAmt);
|
||||
|
||||
aave.deposit{value:ethAmt}(_token, _amt, getReferralCode);
|
||||
|
||||
if (!getIsColl(aave, _token))
|
||||
aave.setUserUseReserveAsCollateral(_token, true);
|
||||
}
|
||||
}
|
||||
|
||||
function _aaveV1Deposit(
|
||||
AaveV1DepositData memory data
|
||||
) internal {
|
||||
for (uint i = 0; i < data.length; i++) {
|
||||
_aaveV1DepositOne(
|
||||
data.aave,
|
||||
data.aaveCore,
|
||||
data.fee,
|
||||
data.tokens[i],
|
||||
data.amts[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function _aaveV1WithdrawOne(
|
||||
AaveV1Interface aave,
|
||||
AaveV1CoreInterface aaveCore,
|
||||
TokenInterface token,
|
||||
uint amt
|
||||
) internal returns (uint) {
|
||||
if (amt > 0) {
|
||||
address _token = address(token) == wethAddr ? ethAddr : address(token);
|
||||
ATokenV1Interface atoken = ATokenV1Interface(aaveCore.getReserveATokenAddress(_token));
|
||||
if (amt == uint(-1)) {
|
||||
amt = getWithdrawBalance(aave, _token);
|
||||
}
|
||||
atoken.redeem(amt);
|
||||
}
|
||||
return amt;
|
||||
}
|
||||
|
||||
function _aaveV1Withdraw(
|
||||
AaveV1Interface aave,
|
||||
AaveV1CoreInterface aaveCore,
|
||||
uint length,
|
||||
TokenInterface[] memory tokens,
|
||||
uint[] memory amts
|
||||
) internal returns (uint[] memory) {
|
||||
uint[] memory finalAmts = new uint[](length);
|
||||
for (uint i = 0; i < length; i++) {
|
||||
finalAmts[i] = _aaveV1WithdrawOne(aave, aaveCore, tokens[i], amts[i]);
|
||||
}
|
||||
return finalAmts;
|
||||
}
|
||||
|
||||
function _aaveV1PaybackOne(
|
||||
AaveV1Interface aave,
|
||||
AaveV1CoreInterface aaveCore,
|
||||
TokenInterface token,
|
||||
uint amt
|
||||
) internal returns (uint) {
|
||||
if (amt > 0) {
|
||||
uint ethAmt;
|
||||
|
||||
bool isEth = address(token) == wethAddr;
|
||||
|
||||
address _token = isEth ? ethAddr : address(token);
|
||||
|
||||
if (amt == uint(-1)) {
|
||||
(uint _amt, uint _fee) = getPaybackBalance(aave, _token);
|
||||
amt = _amt + _fee;
|
||||
}
|
||||
|
||||
if (isEth) {
|
||||
ethAmt = amt;
|
||||
} else {
|
||||
token.approve(address(aaveCore), amt);
|
||||
}
|
||||
|
||||
aave.repay{value:ethAmt}(_token, amt, payable(address(this)));
|
||||
}
|
||||
return amt;
|
||||
}
|
||||
|
||||
function _aaveV1Payback(
|
||||
AaveV1Interface aave,
|
||||
AaveV1CoreInterface aaveCore,
|
||||
uint length,
|
||||
TokenInterface[] memory tokens,
|
||||
uint[] memory amts
|
||||
) internal {
|
||||
for (uint i = 0; i < length; i++) {
|
||||
_aaveV1PaybackOne(aave, aaveCore, tokens[i], amts[i]);
|
||||
}
|
||||
}
|
||||
}
|
200
contracts/mainnet/connectors/refinance/helpers/aaveV2.sol
Normal file
200
contracts/mainnet/connectors/refinance/helpers/aaveV2.sol
Normal file
|
@ -0,0 +1,200 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import { protocolHelpers } from "../helpers.sol";
|
||||
|
||||
import {
|
||||
// AaveV1ProviderInterface,
|
||||
// AaveV1Interface,
|
||||
// AaveV1CoreInterface,
|
||||
AaveV2LendingPoolProviderInterface,
|
||||
AaveV2DataProviderInterface,
|
||||
AaveV2Interface,
|
||||
ATokenV1Interface,
|
||||
CTokenInterface
|
||||
} from "../interfaces.sol";
|
||||
|
||||
import { TokenInterface } from "../../../common/interfaces.sol";
|
||||
|
||||
contract AaveV2Helpers is protocolHelpers {
|
||||
|
||||
struct AaveV2BorrowData {
|
||||
AaveV2Interface aave;
|
||||
uint length;
|
||||
uint fee;
|
||||
Protocol target;
|
||||
TokenInterface[] tokens;
|
||||
CTokenInterface[] ctokens;
|
||||
uint[] amts;
|
||||
uint[] rateModes;
|
||||
}
|
||||
|
||||
struct AaveV2PaybackData {
|
||||
AaveV2Interface aave;
|
||||
AaveV2DataProviderInterface aaveData;
|
||||
uint length;
|
||||
TokenInterface[] tokens;
|
||||
uint[] amts;
|
||||
uint[] rateModes;
|
||||
}
|
||||
|
||||
struct AaveV2WithdrawData {
|
||||
AaveV2Interface aave;
|
||||
AaveV2DataProviderInterface aaveData;
|
||||
uint length;
|
||||
TokenInterface[] tokens;
|
||||
uint[] amts;
|
||||
}
|
||||
|
||||
function _aaveV2BorrowOne(
|
||||
AaveV2Interface aave,
|
||||
uint fee,
|
||||
Protocol target,
|
||||
TokenInterface token,
|
||||
CTokenInterface ctoken,
|
||||
uint amt,
|
||||
uint rateMode
|
||||
) internal returns (uint) {
|
||||
if (amt > 0) {
|
||||
bool isEth = address(token) == wethAddr;
|
||||
|
||||
address _token = isEth ? ethAddr : address(token);
|
||||
|
||||
if (amt == uint(-1)) {
|
||||
amt = getMaxBorrow(target, _token, ctoken, rateMode);
|
||||
}
|
||||
|
||||
(uint feeAmt, uint _amt) = calculateFee(amt, fee, true);
|
||||
|
||||
aave.borrow(address(token), _amt, rateMode, getReferralCode, address(this));
|
||||
convertWethToEth(isEth, token, amt);
|
||||
|
||||
transferFees(_token, feeAmt);
|
||||
}
|
||||
return amt;
|
||||
}
|
||||
|
||||
function _aaveV2Borrow(
|
||||
AaveV2BorrowData memory data
|
||||
) internal returns (uint[] memory) {
|
||||
uint[] memory finalAmts = new uint[](data.length);
|
||||
for (uint i = 0; i < data.length; i++) {
|
||||
finalAmts[i] = _aaveV2BorrowOne(
|
||||
data.aave,
|
||||
data.fee,
|
||||
data.target,
|
||||
data.tokens[i],
|
||||
data.ctokens[i],
|
||||
data.amts[i],
|
||||
data.rateModes[i]
|
||||
);
|
||||
}
|
||||
return finalAmts;
|
||||
}
|
||||
|
||||
function _aaveV2DepositOne(
|
||||
AaveV2Interface aave,
|
||||
AaveV2DataProviderInterface aaveData,
|
||||
uint fee,
|
||||
TokenInterface token,
|
||||
uint amt
|
||||
) internal {
|
||||
if (amt > 0) {
|
||||
(uint feeAmt, uint _amt) = calculateFee(amt, fee, false);
|
||||
|
||||
bool isEth = address(token) == wethAddr;
|
||||
address _token = isEth ? ethAddr : address(token);
|
||||
|
||||
transferFees(_token, feeAmt);
|
||||
|
||||
convertEthToWeth(isEth, token, _amt);
|
||||
|
||||
token.approve(address(aave), _amt);
|
||||
|
||||
aave.deposit(address(token), _amt, address(this), getReferralCode);
|
||||
|
||||
if (!getIsCollV2(aaveData, address(token))) {
|
||||
aave.setUserUseReserveAsCollateral(address(token), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _aaveV2Deposit(
|
||||
AaveV2Interface aave,
|
||||
AaveV2DataProviderInterface aaveData,
|
||||
uint length,
|
||||
uint fee,
|
||||
TokenInterface[] memory tokens,
|
||||
uint[] memory amts
|
||||
) internal {
|
||||
for (uint i = 0; i < length; i++) {
|
||||
_aaveV2DepositOne(aave, aaveData, fee, tokens[i], amts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function _aaveV2WithdrawOne(
|
||||
AaveV2Interface aave,
|
||||
AaveV2DataProviderInterface aaveData,
|
||||
TokenInterface token,
|
||||
uint amt
|
||||
) internal returns (uint _amt) {
|
||||
if (amt > 0) {
|
||||
bool isEth = address(token) == wethAddr;
|
||||
|
||||
aave.withdraw(address(token), amt, address(this));
|
||||
|
||||
_amt = amt == uint(-1) ? getWithdrawBalanceV2(aaveData, address(token)) : amt;
|
||||
|
||||
convertWethToEth(isEth, token, _amt);
|
||||
}
|
||||
}
|
||||
|
||||
function _aaveV2Withdraw(
|
||||
AaveV2WithdrawData memory data
|
||||
) internal returns (uint[] memory) {
|
||||
uint[] memory finalAmts = new uint[](data.length);
|
||||
for (uint i = 0; i < data.length; i++) {
|
||||
finalAmts[i] = _aaveV2WithdrawOne(
|
||||
data.aave,
|
||||
data.aaveData,
|
||||
data.tokens[i],
|
||||
data.amts[i]
|
||||
);
|
||||
}
|
||||
return finalAmts;
|
||||
}
|
||||
|
||||
function _aaveV2PaybackOne(
|
||||
AaveV2Interface aave,
|
||||
AaveV2DataProviderInterface aaveData,
|
||||
TokenInterface token,
|
||||
uint amt,
|
||||
uint rateMode
|
||||
) internal returns (uint _amt) {
|
||||
if (amt > 0) {
|
||||
bool isEth = address(token) == wethAddr;
|
||||
|
||||
_amt = amt == uint(-1) ? getPaybackBalanceV2(aaveData, address(token), rateMode) : amt;
|
||||
|
||||
convertEthToWeth(isEth, token, _amt);
|
||||
|
||||
token.approve(address(aave), _amt);
|
||||
|
||||
aave.repay(address(token), _amt, rateMode, address(this));
|
||||
}
|
||||
}
|
||||
|
||||
function _aaveV2Payback(
|
||||
AaveV2PaybackData memory data
|
||||
) internal {
|
||||
for (uint i = 0; i < data.length; i++) {
|
||||
_aaveV2PaybackOne(
|
||||
data.aave,
|
||||
data.aaveData,
|
||||
data.tokens[i],
|
||||
data.amts[i],
|
||||
data.rateModes[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
160
contracts/mainnet/connectors/refinance/helpers/compound.sol
Normal file
160
contracts/mainnet/connectors/refinance/helpers/compound.sol
Normal file
|
@ -0,0 +1,160 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import { protocolHelpers } from "../helpers.sol";
|
||||
|
||||
import {
|
||||
ComptrollerInterface,
|
||||
CTokenInterface,
|
||||
CompoundMappingInterface,
|
||||
CETHInterface
|
||||
} from "../interfaces.sol";
|
||||
|
||||
import { TokenInterface } from "../../../common/interfaces.sol";
|
||||
|
||||
|
||||
|
||||
contract CompoundHelpers is protocolHelpers {
|
||||
|
||||
struct CompoundBorrowData {
|
||||
uint length;
|
||||
uint fee;
|
||||
Protocol target;
|
||||
CTokenInterface[] ctokens;
|
||||
TokenInterface[] tokens;
|
||||
uint[] amts;
|
||||
uint[] rateModes;
|
||||
}
|
||||
|
||||
function _compEnterMarkets(uint length, CTokenInterface[] memory ctokens) internal {
|
||||
ComptrollerInterface troller = ComptrollerInterface(getComptrollerAddress);
|
||||
address[] memory _cTokens = new address[](length);
|
||||
|
||||
for (uint i = 0; i < length; i++) {
|
||||
_cTokens[i] = address(ctokens[i]);
|
||||
}
|
||||
troller.enterMarkets(_cTokens);
|
||||
}
|
||||
|
||||
function _compBorrowOne(
|
||||
uint fee,
|
||||
CTokenInterface ctoken,
|
||||
TokenInterface token,
|
||||
uint amt,
|
||||
Protocol target,
|
||||
uint rateMode
|
||||
) internal returns (uint) {
|
||||
if (amt > 0) {
|
||||
address _token = address(token) == wethAddr ? ethAddr : address(token);
|
||||
|
||||
if (amt == uint(-1)) {
|
||||
amt = getMaxBorrow(target, address(token), ctoken, rateMode);
|
||||
}
|
||||
|
||||
(uint feeAmt, uint _amt) = calculateFee(amt, fee, true);
|
||||
|
||||
require(ctoken.borrow(_amt) == 0, "borrow-failed-collateral?");
|
||||
transferFees(_token, feeAmt);
|
||||
}
|
||||
return amt;
|
||||
}
|
||||
|
||||
function _compBorrow(
|
||||
CompoundBorrowData memory data
|
||||
) internal returns (uint[] memory) {
|
||||
uint[] memory finalAmts = new uint[](data.length);
|
||||
for (uint i = 0; i < data.length; i++) {
|
||||
finalAmts[i] = _compBorrowOne(
|
||||
data.fee,
|
||||
data.ctokens[i],
|
||||
data.tokens[i],
|
||||
data.amts[i],
|
||||
data.target,
|
||||
data.rateModes[i]
|
||||
);
|
||||
}
|
||||
return finalAmts;
|
||||
}
|
||||
|
||||
function _compDepositOne(uint fee, CTokenInterface ctoken, TokenInterface token, uint amt) internal {
|
||||
if (amt > 0) {
|
||||
address _token = address(token) == wethAddr ? ethAddr : address(token);
|
||||
|
||||
(uint feeAmt, uint _amt) = calculateFee(amt, fee, false);
|
||||
|
||||
if (_token != ethAddr) {
|
||||
token.approve(address(ctoken), _amt);
|
||||
require(ctoken.mint(_amt) == 0, "deposit-failed");
|
||||
} else {
|
||||
CETHInterface(address(ctoken)).mint{value:_amt}();
|
||||
}
|
||||
transferFees(_token, feeAmt);
|
||||
}
|
||||
}
|
||||
|
||||
function _compDeposit(
|
||||
uint length,
|
||||
uint fee,
|
||||
CTokenInterface[] memory ctokens,
|
||||
TokenInterface[] memory tokens,
|
||||
uint[] memory amts
|
||||
) internal {
|
||||
for (uint i = 0; i < length; i++) {
|
||||
_compDepositOne(fee, ctokens[i], tokens[i], amts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function _compWithdrawOne(CTokenInterface ctoken, TokenInterface token, uint amt) internal returns (uint) {
|
||||
if (amt > 0) {
|
||||
if (amt == uint(-1)) {
|
||||
bool isEth = address(token) == wethAddr;
|
||||
uint initalBal = isEth ? address(this).balance : token.balanceOf(address(this));
|
||||
require(ctoken.redeem(ctoken.balanceOf(address(this))) == 0, "withdraw-failed");
|
||||
uint finalBal = isEth ? address(this).balance : token.balanceOf(address(this));
|
||||
amt = sub(finalBal, initalBal);
|
||||
} else {
|
||||
require(ctoken.redeemUnderlying(amt) == 0, "withdraw-failed");
|
||||
}
|
||||
}
|
||||
return amt;
|
||||
}
|
||||
|
||||
function _compWithdraw(
|
||||
uint length,
|
||||
CTokenInterface[] memory ctokens,
|
||||
TokenInterface[] memory tokens,
|
||||
uint[] memory amts
|
||||
) internal returns(uint[] memory) {
|
||||
uint[] memory finalAmts = new uint[](length);
|
||||
for (uint i = 0; i < length; i++) {
|
||||
finalAmts[i] = _compWithdrawOne(ctokens[i], tokens[i], amts[i]);
|
||||
}
|
||||
return finalAmts;
|
||||
}
|
||||
|
||||
function _compPaybackOne(CTokenInterface ctoken, TokenInterface token, uint amt) internal returns (uint) {
|
||||
if (amt > 0) {
|
||||
if (amt == uint(-1)) {
|
||||
amt = ctoken.borrowBalanceCurrent(address(this));
|
||||
}
|
||||
if (address(token) != wethAddr) {
|
||||
token.approve(address(ctoken), amt);
|
||||
require(ctoken.repayBorrow(amt) == 0, "repay-failed.");
|
||||
} else {
|
||||
CETHInterface(address(ctoken)).repayBorrow{value:amt}();
|
||||
}
|
||||
}
|
||||
return amt;
|
||||
}
|
||||
|
||||
function _compPayback(
|
||||
uint length,
|
||||
CTokenInterface[] memory ctokens,
|
||||
TokenInterface[] memory tokens,
|
||||
uint[] memory amts
|
||||
) internal {
|
||||
for (uint i = 0; i < length; i++) {
|
||||
_compPaybackOne(ctokens[i], tokens[i], amts[i]);
|
||||
}
|
||||
}
|
||||
}
|
113
contracts/mainnet/connectors/refinance/interfaces.sol
Normal file
113
contracts/mainnet/connectors/refinance/interfaces.sol
Normal file
|
@ -0,0 +1,113 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
// Compound Helpers
|
||||
interface CTokenInterface {
|
||||
function mint(uint mintAmount) external returns (uint);
|
||||
function redeem(uint redeemTokens) external returns (uint);
|
||||
function borrow(uint borrowAmount) external returns (uint);
|
||||
function repayBorrow(uint repayAmount) external returns (uint);
|
||||
|
||||
function borrowBalanceCurrent(address account) external returns (uint);
|
||||
function redeemUnderlying(uint redeemAmount) external returns (uint);
|
||||
|
||||
function balanceOf(address owner) external view returns (uint256 balance);
|
||||
}
|
||||
|
||||
interface CETHInterface {
|
||||
function mint() external payable;
|
||||
function repayBorrow() external payable;
|
||||
}
|
||||
|
||||
interface CompoundMappingInterface {
|
||||
function cTokenMapping(string calldata tokenId) external view returns (address);
|
||||
function getMapping(string calldata tokenId) external view returns (address, address);
|
||||
}
|
||||
|
||||
interface ComptrollerInterface {
|
||||
function enterMarkets(address[] calldata cTokens) external returns (uint[] memory);
|
||||
}
|
||||
// End Compound Helpers
|
||||
|
||||
// Aave v1 Helpers
|
||||
interface AaveV1Interface {
|
||||
function deposit(address _reserve, uint256 _amount, uint16 _referralCode) external payable;
|
||||
function redeemUnderlying(
|
||||
address _reserve,
|
||||
address payable _user,
|
||||
uint256 _amount,
|
||||
uint256 _aTokenBalanceAfterRedeem
|
||||
) external;
|
||||
|
||||
function setUserUseReserveAsCollateral(address _reserve, bool _useAsCollateral) external;
|
||||
function getUserReserveData(address _reserve, address _user) external view returns (
|
||||
uint256 currentATokenBalance,
|
||||
uint256 currentBorrowBalance,
|
||||
uint256 principalBorrowBalance,
|
||||
uint256 borrowRateMode,
|
||||
uint256 borrowRate,
|
||||
uint256 liquidityRate,
|
||||
uint256 originationFee,
|
||||
uint256 variableBorrowIndex,
|
||||
uint256 lastUpdateTimestamp,
|
||||
bool usageAsCollateralEnabled
|
||||
);
|
||||
function borrow(address _reserve, uint256 _amount, uint256 _interestRateMode, uint16 _referralCode) external;
|
||||
function repay(address _reserve, uint256 _amount, address payable _onBehalfOf) external payable;
|
||||
}
|
||||
|
||||
interface AaveV1ProviderInterface {
|
||||
function getLendingPool() external view returns (address);
|
||||
function getLendingPoolCore() external view returns (address);
|
||||
}
|
||||
|
||||
interface AaveV1CoreInterface {
|
||||
function getReserveATokenAddress(address _reserve) external view returns (address);
|
||||
}
|
||||
|
||||
interface ATokenV1Interface {
|
||||
function redeem(uint256 _amount) external;
|
||||
function balanceOf(address _user) external view returns(uint256);
|
||||
function principalBalanceOf(address _user) external view returns(uint256);
|
||||
|
||||
function allowance(address, address) external view returns (uint);
|
||||
function approve(address, uint) external;
|
||||
function transfer(address, uint) external returns (bool);
|
||||
function transferFrom(address, address, uint) external returns (bool);
|
||||
}
|
||||
// End Aave v1 Helpers
|
||||
|
||||
// Aave v2 Helpers
|
||||
interface AaveV2Interface {
|
||||
function deposit(address _asset, uint256 _amount, address _onBehalfOf, uint16 _referralCode) external;
|
||||
function withdraw(address _asset, uint256 _amount, address _to) external;
|
||||
function borrow(
|
||||
address _asset,
|
||||
uint256 _amount,
|
||||
uint256 _interestRateMode,
|
||||
uint16 _referralCode,
|
||||
address _onBehalfOf
|
||||
) external;
|
||||
function repay(address _asset, uint256 _amount, uint256 _rateMode, address _onBehalfOf) external;
|
||||
function setUserUseReserveAsCollateral(address _asset, bool _useAsCollateral) external;
|
||||
}
|
||||
|
||||
interface AaveV2LendingPoolProviderInterface {
|
||||
function getLendingPool() external view returns (address);
|
||||
}
|
||||
|
||||
// Aave Protocol Data Provider
|
||||
interface AaveV2DataProviderInterface {
|
||||
function getUserReserveData(address _asset, address _user) external view returns (
|
||||
uint256 currentATokenBalance,
|
||||
uint256 currentStableDebt,
|
||||
uint256 currentVariableDebt,
|
||||
uint256 principalStableDebt,
|
||||
uint256 scaledVariableDebt,
|
||||
uint256 stableBorrowRate,
|
||||
uint256 liquidityRate,
|
||||
uint40 stableRateLastUpdated,
|
||||
bool usageAsCollateralEnabled
|
||||
);
|
||||
}
|
||||
// End Aave v2 Helpers
|
339
contracts/mainnet/connectors/refinance/main.sol
Normal file
339
contracts/mainnet/connectors/refinance/main.sol
Normal file
|
@ -0,0 +1,339 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/**
|
||||
* @title Refinance.
|
||||
* @dev Refinancing.
|
||||
*/
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
|
||||
import {
|
||||
AaveV1ProviderInterface,
|
||||
AaveV1Interface,
|
||||
AaveV1CoreInterface,
|
||||
AaveV2LendingPoolProviderInterface,
|
||||
AaveV2DataProviderInterface,
|
||||
AaveV2Interface,
|
||||
ComptrollerInterface,
|
||||
CTokenInterface,
|
||||
CompoundMappingInterface
|
||||
} from "./interfaces.sol";
|
||||
|
||||
|
||||
import { AaveV1Helpers } from "./helpers/aaveV1.sol";
|
||||
import { AaveV2Helpers } from "./helpers/aaveV2.sol";
|
||||
import { CompoundHelpers } from "./helpers/compound.sol";
|
||||
|
||||
|
||||
contract RefinanceResolver is CompoundHelpers, AaveV1Helpers, AaveV2Helpers {
|
||||
|
||||
struct RefinanceData {
|
||||
Protocol source;
|
||||
Protocol target;
|
||||
uint collateralFee;
|
||||
uint debtFee;
|
||||
address[] tokens;
|
||||
string[] ctokenIds;
|
||||
uint[] borrowAmts;
|
||||
uint[] withdrawAmts;
|
||||
uint[] borrowRateModes;
|
||||
uint[] paybackRateModes;
|
||||
}
|
||||
|
||||
struct RefinanceInternalData {
|
||||
AaveV2Interface aaveV2;
|
||||
AaveV1Interface aaveV1;
|
||||
AaveV1CoreInterface aaveCore;
|
||||
AaveV2DataProviderInterface aaveData;
|
||||
uint[] depositAmts;
|
||||
uint[] paybackAmts;
|
||||
TokenInterface[] tokens;
|
||||
CTokenInterface[] _ctokens;
|
||||
}
|
||||
|
||||
function _refinance(RefinanceData calldata data)
|
||||
internal returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
|
||||
require(data.source != data.target, "source-and-target-unequal");
|
||||
|
||||
uint length = data.tokens.length;
|
||||
|
||||
require(data.borrowAmts.length == length, "length-mismatch");
|
||||
require(data.withdrawAmts.length == length, "length-mismatch");
|
||||
require(data.borrowRateModes.length == length, "length-mismatch");
|
||||
require(data.paybackRateModes.length == length, "length-mismatch");
|
||||
require(data.ctokenIds.length == length, "length-mismatch");
|
||||
|
||||
RefinanceInternalData memory refinanceInternalData;
|
||||
|
||||
refinanceInternalData.aaveV2 = AaveV2Interface(getAaveV2Provider.getLendingPool());
|
||||
refinanceInternalData.aaveV1 = AaveV1Interface(getAaveProvider.getLendingPool());
|
||||
refinanceInternalData.aaveCore = AaveV1CoreInterface(getAaveProvider.getLendingPoolCore());
|
||||
refinanceInternalData.aaveData = getAaveV2DataProvider;
|
||||
|
||||
refinanceInternalData.depositAmts;
|
||||
refinanceInternalData.paybackAmts;
|
||||
|
||||
refinanceInternalData.tokens = getTokenInterfaces(length, data.tokens);
|
||||
refinanceInternalData._ctokens = getCtokenInterfaces(length, data.ctokenIds);
|
||||
|
||||
if (data.source == Protocol.Aave && data.target == Protocol.AaveV2) {
|
||||
AaveV2BorrowData memory _aaveV2BorrowData;
|
||||
|
||||
_aaveV2BorrowData.aave = refinanceInternalData.aaveV2;
|
||||
_aaveV2BorrowData.length = length;
|
||||
_aaveV2BorrowData.fee = data.debtFee;
|
||||
_aaveV2BorrowData.target = data.source;
|
||||
_aaveV2BorrowData.tokens = refinanceInternalData.tokens;
|
||||
_aaveV2BorrowData.ctokens = refinanceInternalData._ctokens;
|
||||
_aaveV2BorrowData.amts = data.borrowAmts;
|
||||
_aaveV2BorrowData.rateModes = data.borrowRateModes;
|
||||
{
|
||||
refinanceInternalData.paybackAmts = _aaveV2Borrow(_aaveV2BorrowData);
|
||||
_aaveV1Payback(
|
||||
refinanceInternalData.aaveV1,
|
||||
refinanceInternalData.aaveCore,
|
||||
length,
|
||||
refinanceInternalData.tokens,
|
||||
refinanceInternalData.paybackAmts
|
||||
);
|
||||
refinanceInternalData.depositAmts = _aaveV1Withdraw(
|
||||
refinanceInternalData.aaveV1,
|
||||
refinanceInternalData.aaveCore,
|
||||
length,
|
||||
refinanceInternalData.tokens,
|
||||
data.withdrawAmts
|
||||
);
|
||||
_aaveV2Deposit(
|
||||
refinanceInternalData.aaveV2,
|
||||
refinanceInternalData.aaveData,
|
||||
length,
|
||||
data.collateralFee,
|
||||
refinanceInternalData.tokens,
|
||||
refinanceInternalData.depositAmts
|
||||
);
|
||||
}
|
||||
} else if (data.source == Protocol.Aave && data.target == Protocol.Compound) {
|
||||
_compEnterMarkets(length, refinanceInternalData._ctokens);
|
||||
|
||||
CompoundBorrowData memory _compoundBorrowData;
|
||||
|
||||
_compoundBorrowData.length = length;
|
||||
_compoundBorrowData.fee = data.debtFee;
|
||||
_compoundBorrowData.target = data.source;
|
||||
_compoundBorrowData.ctokens = refinanceInternalData._ctokens;
|
||||
_compoundBorrowData.tokens = refinanceInternalData.tokens;
|
||||
_compoundBorrowData.amts = data.borrowAmts;
|
||||
_compoundBorrowData.rateModes = data.borrowRateModes;
|
||||
|
||||
refinanceInternalData.paybackAmts = _compBorrow(_compoundBorrowData);
|
||||
|
||||
_aaveV1Payback(
|
||||
refinanceInternalData.aaveV1,
|
||||
refinanceInternalData.aaveCore,
|
||||
length,
|
||||
refinanceInternalData.tokens,
|
||||
refinanceInternalData.paybackAmts
|
||||
);
|
||||
refinanceInternalData.depositAmts = _aaveV1Withdraw(
|
||||
refinanceInternalData.aaveV1,
|
||||
refinanceInternalData.aaveCore,
|
||||
length,
|
||||
refinanceInternalData.tokens,
|
||||
data.withdrawAmts
|
||||
);
|
||||
_compDeposit(
|
||||
length,
|
||||
data.collateralFee,
|
||||
refinanceInternalData._ctokens,
|
||||
refinanceInternalData.tokens,
|
||||
refinanceInternalData.depositAmts
|
||||
);
|
||||
} else if (data.source == Protocol.AaveV2 && data.target == Protocol.Aave) {
|
||||
|
||||
AaveV1BorrowData memory _aaveV1BorrowData;
|
||||
AaveV2PaybackData memory _aaveV2PaybackData;
|
||||
AaveV2WithdrawData memory _aaveV2WithdrawData;
|
||||
|
||||
{
|
||||
_aaveV1BorrowData.aave = refinanceInternalData.aaveV1;
|
||||
_aaveV1BorrowData.length = length;
|
||||
_aaveV1BorrowData.fee = data.debtFee;
|
||||
_aaveV1BorrowData.target = data.source;
|
||||
_aaveV1BorrowData.tokens = refinanceInternalData.tokens;
|
||||
_aaveV1BorrowData.ctokens = refinanceInternalData._ctokens;
|
||||
_aaveV1BorrowData.amts = data.borrowAmts;
|
||||
_aaveV1BorrowData.borrowRateModes = data.borrowRateModes;
|
||||
_aaveV1BorrowData.paybackRateModes = data.paybackRateModes;
|
||||
|
||||
refinanceInternalData.paybackAmts = _aaveV1Borrow(_aaveV1BorrowData);
|
||||
}
|
||||
|
||||
{
|
||||
_aaveV2PaybackData.aave = refinanceInternalData.aaveV2;
|
||||
_aaveV2PaybackData.aaveData = refinanceInternalData.aaveData;
|
||||
_aaveV2PaybackData.length = length;
|
||||
_aaveV2PaybackData.tokens = refinanceInternalData.tokens;
|
||||
_aaveV2PaybackData.amts = refinanceInternalData.paybackAmts;
|
||||
_aaveV2PaybackData.rateModes = data.paybackRateModes;
|
||||
_aaveV2Payback(_aaveV2PaybackData);
|
||||
}
|
||||
|
||||
{
|
||||
_aaveV2WithdrawData.aave = refinanceInternalData.aaveV2;
|
||||
_aaveV2WithdrawData.aaveData = refinanceInternalData.aaveData;
|
||||
_aaveV2WithdrawData.length = length;
|
||||
_aaveV2WithdrawData.tokens = refinanceInternalData.tokens;
|
||||
_aaveV2WithdrawData.amts = data.withdrawAmts;
|
||||
refinanceInternalData.depositAmts = _aaveV2Withdraw(_aaveV2WithdrawData);
|
||||
}
|
||||
{
|
||||
AaveV1DepositData memory _aaveV1DepositData;
|
||||
|
||||
_aaveV1DepositData.aave = refinanceInternalData.aaveV1;
|
||||
_aaveV1DepositData.aaveCore = refinanceInternalData.aaveCore;
|
||||
_aaveV1DepositData.length = length;
|
||||
_aaveV1DepositData.fee = data.collateralFee;
|
||||
_aaveV1DepositData.tokens = refinanceInternalData.tokens;
|
||||
_aaveV1DepositData.amts = refinanceInternalData.depositAmts;
|
||||
|
||||
_aaveV1Deposit(_aaveV1DepositData);
|
||||
}
|
||||
} else if (data.source == Protocol.AaveV2 && data.target == Protocol.Compound) {
|
||||
_compEnterMarkets(length, refinanceInternalData._ctokens);
|
||||
|
||||
{
|
||||
CompoundBorrowData memory _compoundBorrowData;
|
||||
|
||||
_compoundBorrowData.length = length;
|
||||
_compoundBorrowData.fee = data.debtFee;
|
||||
_compoundBorrowData.target = data.source;
|
||||
_compoundBorrowData.ctokens = refinanceInternalData._ctokens;
|
||||
_compoundBorrowData.tokens = refinanceInternalData.tokens;
|
||||
_compoundBorrowData.amts = data.borrowAmts;
|
||||
_compoundBorrowData.rateModes = data.borrowRateModes;
|
||||
|
||||
refinanceInternalData.paybackAmts = _compBorrow(_compoundBorrowData);
|
||||
}
|
||||
|
||||
AaveV2PaybackData memory _aaveV2PaybackData;
|
||||
|
||||
_aaveV2PaybackData.aave = refinanceInternalData.aaveV2;
|
||||
_aaveV2PaybackData.aaveData = refinanceInternalData.aaveData;
|
||||
_aaveV2PaybackData.length = length;
|
||||
_aaveV2PaybackData.tokens = refinanceInternalData.tokens;
|
||||
_aaveV2PaybackData.amts = refinanceInternalData.paybackAmts;
|
||||
_aaveV2PaybackData.rateModes = data.paybackRateModes;
|
||||
|
||||
_aaveV2Payback(_aaveV2PaybackData);
|
||||
|
||||
{
|
||||
AaveV2WithdrawData memory _aaveV2WithdrawData;
|
||||
|
||||
_aaveV2WithdrawData.aave = refinanceInternalData.aaveV2;
|
||||
_aaveV2WithdrawData.aaveData = refinanceInternalData.aaveData;
|
||||
_aaveV2WithdrawData.length = length;
|
||||
_aaveV2WithdrawData.tokens = refinanceInternalData.tokens;
|
||||
_aaveV2WithdrawData.amts = data.withdrawAmts;
|
||||
refinanceInternalData.depositAmts = _aaveV2Withdraw(_aaveV2WithdrawData);
|
||||
}
|
||||
_compDeposit(
|
||||
length,
|
||||
data.collateralFee,
|
||||
refinanceInternalData._ctokens,
|
||||
refinanceInternalData.tokens,
|
||||
refinanceInternalData.depositAmts
|
||||
);
|
||||
} else if (data.source == Protocol.Compound && data.target == Protocol.Aave) {
|
||||
|
||||
AaveV1BorrowData memory _aaveV1BorrowData;
|
||||
|
||||
_aaveV1BorrowData.aave = refinanceInternalData.aaveV1;
|
||||
_aaveV1BorrowData.length = length;
|
||||
_aaveV1BorrowData.fee = data.debtFee;
|
||||
_aaveV1BorrowData.target = data.source;
|
||||
_aaveV1BorrowData.tokens = refinanceInternalData.tokens;
|
||||
_aaveV1BorrowData.ctokens = refinanceInternalData._ctokens;
|
||||
_aaveV1BorrowData.amts = data.borrowAmts;
|
||||
_aaveV1BorrowData.borrowRateModes = data.borrowRateModes;
|
||||
_aaveV1BorrowData.paybackRateModes = data.paybackRateModes;
|
||||
|
||||
refinanceInternalData.paybackAmts = _aaveV1Borrow(_aaveV1BorrowData);
|
||||
{
|
||||
_compPayback(
|
||||
length,
|
||||
refinanceInternalData._ctokens,
|
||||
refinanceInternalData.tokens,
|
||||
refinanceInternalData.paybackAmts
|
||||
);
|
||||
refinanceInternalData.depositAmts = _compWithdraw(
|
||||
length,
|
||||
refinanceInternalData._ctokens,
|
||||
refinanceInternalData.tokens,
|
||||
data.withdrawAmts
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
AaveV1DepositData memory _aaveV1DepositData;
|
||||
|
||||
_aaveV1DepositData.aave = refinanceInternalData.aaveV1;
|
||||
_aaveV1DepositData.aaveCore = refinanceInternalData.aaveCore;
|
||||
_aaveV1DepositData.length = length;
|
||||
_aaveV1DepositData.fee = data.collateralFee;
|
||||
_aaveV1DepositData.tokens = refinanceInternalData.tokens;
|
||||
_aaveV1DepositData.amts = refinanceInternalData.depositAmts;
|
||||
|
||||
_aaveV1Deposit(_aaveV1DepositData);
|
||||
}
|
||||
} else if (data.source == Protocol.Compound && data.target == Protocol.AaveV2) {
|
||||
AaveV2BorrowData memory _aaveV2BorrowData;
|
||||
|
||||
_aaveV2BorrowData.aave = refinanceInternalData.aaveV2;
|
||||
_aaveV2BorrowData.length = length;
|
||||
_aaveV2BorrowData.fee = data.debtFee;
|
||||
_aaveV2BorrowData.target = data.source;
|
||||
_aaveV2BorrowData.tokens = refinanceInternalData.tokens;
|
||||
_aaveV2BorrowData.ctokens = refinanceInternalData._ctokens;
|
||||
_aaveV2BorrowData.amts = data.borrowAmts;
|
||||
_aaveV2BorrowData.rateModes = data.borrowRateModes;
|
||||
|
||||
refinanceInternalData.paybackAmts = _aaveV2Borrow(_aaveV2BorrowData);
|
||||
_compPayback(length, refinanceInternalData._ctokens, refinanceInternalData.tokens, refinanceInternalData.paybackAmts);
|
||||
refinanceInternalData.depositAmts = _compWithdraw(
|
||||
length,
|
||||
refinanceInternalData._ctokens,
|
||||
refinanceInternalData.tokens,
|
||||
data.withdrawAmts
|
||||
);
|
||||
_aaveV2Deposit(
|
||||
refinanceInternalData.aaveV2,
|
||||
refinanceInternalData.aaveData,
|
||||
length,
|
||||
data.collateralFee,
|
||||
refinanceInternalData.tokens,
|
||||
refinanceInternalData.depositAmts
|
||||
);
|
||||
} else {
|
||||
revert("invalid-options");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @dev Refinance
|
||||
* @notice Refinancing between AaveV1, AaveV2 and Compound
|
||||
* @param data refinance data.
|
||||
*/
|
||||
function refinance(RefinanceData calldata data)
|
||||
external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
(_eventName, _eventParam) = _refinance(data);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2Refinance is RefinanceResolver {
|
||||
string public name = "Refinance-v1.0";
|
||||
}
|
|
@ -57,7 +57,7 @@ abstract contract Helpers is DSMath, Basic {
|
|||
* @dev Collateral Join address is ETH type collateral.
|
||||
*/
|
||||
function isEth(address tknAddr) internal pure returns (bool) {
|
||||
return tknAddr == ethAddr ? true : false;
|
||||
return tknAddr == wethAddr ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
6
contracts/mainnet/connectors/weth/events.sol
Normal file
6
contracts/mainnet/connectors/weth/events.sol
Normal file
|
@ -0,0 +1,6 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
event LogDeposit(uint256 tokenAmt, uint256 getId, uint256 setId);
|
||||
event LogWithdraw(uint256 tokenAmt, uint256 getId, uint256 setId);
|
||||
}
|
8
contracts/mainnet/connectors/weth/helpers.sol
Normal file
8
contracts/mainnet/connectors/weth/helpers.sol
Normal file
|
@ -0,0 +1,8 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
|
||||
|
||||
abstract contract Helpers {
|
||||
TokenInterface constant internal wethContract = TokenInterface(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
|
||||
}
|
65
contracts/mainnet/connectors/weth/main.sol
Normal file
65
contracts/mainnet/connectors/weth/main.sol
Normal file
|
@ -0,0 +1,65 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
/**
|
||||
* @title WETH.
|
||||
* @dev Wrap and Unwrap WETH.
|
||||
*/
|
||||
|
||||
import { DSMath } from "../../common/math.sol";
|
||||
import { Basic } from "../../common/basic.sol";
|
||||
import { Events } from "./events.sol";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
|
||||
abstract contract Resolver is Events, DSMath, Basic, Helpers {
|
||||
|
||||
/**
|
||||
* @dev Deposit ETH into WETH.
|
||||
* @notice Wrap ETH into WETH
|
||||
* @param amt The amount of ETH to deposit. (For max: `uint256(-1)`)
|
||||
* @param getId ID to retrieve amt.
|
||||
* @param setId ID stores the amount of ETH deposited.
|
||||
*/
|
||||
function deposit(
|
||||
uint256 amt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) public payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _amt = getUint(getId, amt);
|
||||
|
||||
_amt = _amt == uint(-1) ? address(this).balance : _amt;
|
||||
wethContract.deposit{value: _amt}();
|
||||
|
||||
setUint(setId, _amt);
|
||||
|
||||
_eventName = "LogDeposit(uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(_amt, getId, setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Withdraw ETH from WETH from Smart Account
|
||||
* @notice Unwrap ETH from WETH
|
||||
* @param amt The amount of weth to withdraw. (For max: `uint256(-1)`)
|
||||
* @param getId ID to retrieve amt.
|
||||
* @param setId ID stores the amount of ETH withdrawn.
|
||||
*/
|
||||
function withdraw(
|
||||
uint amt,
|
||||
uint getId,
|
||||
uint setId
|
||||
) public payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _amt = getUint(getId, amt);
|
||||
|
||||
_amt = _amt == uint(-1) ? wethContract.balanceOf(address(this)) : _amt;
|
||||
wethContract.approve(wethAddr, _amt);
|
||||
wethContract.withdraw(_amt);
|
||||
|
||||
setUint(setId, _amt);
|
||||
|
||||
_eventName = "LogWithdraw(uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(_amt, getId, setId);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2WETH is Resolver {
|
||||
string constant public name = "WETH-v1.0";
|
||||
}
|
462
contracts/mainnet/connectors_old/polygon-bridge.sol
Normal file
462
contracts/mainnet/connectors_old/polygon-bridge.sol
Normal file
|
@ -0,0 +1,462 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
interface TokenInterface {
|
||||
function approve(address, uint256) external;
|
||||
function transfer(address, uint) external;
|
||||
function transferFrom(address, address, uint) external;
|
||||
function deposit() external payable;
|
||||
function withdraw(uint) external;
|
||||
function balanceOf(address) external view returns (uint);
|
||||
function decimals() external view returns (uint);
|
||||
}
|
||||
|
||||
interface MemoryInterface {
|
||||
function getUint(uint id) external returns (uint num);
|
||||
function setUint(uint id, uint val) external;
|
||||
}
|
||||
|
||||
interface InstaMapping {
|
||||
function cTokenMapping(address) external view returns (address);
|
||||
function gemJoinMapping(bytes32) external view returns (address);
|
||||
}
|
||||
|
||||
interface AccountInterface {
|
||||
function enable(address) external;
|
||||
function disable(address) external;
|
||||
function isAuth(address) external view returns (bool);
|
||||
}
|
||||
|
||||
abstract contract Stores {
|
||||
|
||||
/**
|
||||
* @dev Return ethereum address
|
||||
*/
|
||||
address constant internal ethAddr = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||
|
||||
/**
|
||||
* @dev Return Wrapped ETH address
|
||||
*/
|
||||
address constant internal wethAddr = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
|
||||
|
||||
/**
|
||||
* @dev Return memory variable address
|
||||
*/
|
||||
MemoryInterface constant internal instaMemory = MemoryInterface(0x8a5419CfC711B2343c17a6ABf4B2bAFaBb06957F);
|
||||
|
||||
/**
|
||||
* @dev Return InstaDApp Mapping Addresses
|
||||
*/
|
||||
InstaMapping constant internal instaMapping = InstaMapping(0xe81F70Cc7C0D46e12d70efc60607F16bbD617E88);
|
||||
|
||||
/**
|
||||
* @dev Get Uint value from InstaMemory Contract.
|
||||
*/
|
||||
function getUint(uint getId, uint val) internal returns (uint returnVal) {
|
||||
returnVal = getId == 0 ? val : instaMemory.getUint(getId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Set Uint value in InstaMemory Contract.
|
||||
*/
|
||||
function setUint(uint setId, uint val) virtual internal {
|
||||
if (setId != 0) instaMemory.setUint(setId, val);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Wrappers over Solidity's arithmetic operations with added overflow
|
||||
* checks.
|
||||
*
|
||||
* Arithmetic operations in Solidity wrap on overflow. This can easily result
|
||||
* in bugs, because programmers usually assume that an overflow raises an
|
||||
* error, which is the standard behavior in high level programming languages.
|
||||
* `SafeMath` restores this intuition by reverting the transaction when an
|
||||
* operation overflows.
|
||||
*
|
||||
* Using this library instead of the unchecked operations eliminates an entire
|
||||
* class of bugs, so it's recommended to use it always.
|
||||
*/
|
||||
library SafeMath {
|
||||
/**
|
||||
* @dev Returns the addition of two unsigned integers, with an overflow flag.
|
||||
*
|
||||
* _Available since v3.4._
|
||||
*/
|
||||
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
|
||||
uint256 c = a + b;
|
||||
if (c < a) return (false, 0);
|
||||
return (true, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
|
||||
*
|
||||
* _Available since v3.4._
|
||||
*/
|
||||
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
|
||||
if (b > a) return (false, 0);
|
||||
return (true, a - b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
|
||||
*
|
||||
* _Available since v3.4._
|
||||
*/
|
||||
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
|
||||
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
|
||||
// benefit is lost if 'b' is also tested.
|
||||
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
|
||||
if (a == 0) return (true, 0);
|
||||
uint256 c = a * b;
|
||||
if (c / a != b) return (false, 0);
|
||||
return (true, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the division of two unsigned integers, with a division by zero flag.
|
||||
*
|
||||
* _Available since v3.4._
|
||||
*/
|
||||
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
|
||||
if (b == 0) return (false, 0);
|
||||
return (true, a / b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
|
||||
*
|
||||
* _Available since v3.4._
|
||||
*/
|
||||
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
|
||||
if (b == 0) return (false, 0);
|
||||
return (true, a % b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the addition of two unsigned integers, reverting on
|
||||
* overflow.
|
||||
*
|
||||
* Counterpart to Solidity's `+` operator.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - Addition cannot overflow.
|
||||
*/
|
||||
function add(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
uint256 c = a + b;
|
||||
require(c >= a, "SafeMath: addition overflow");
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the subtraction of two unsigned integers, reverting on
|
||||
* overflow (when the result is negative).
|
||||
*
|
||||
* Counterpart to Solidity's `-` operator.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - Subtraction cannot overflow.
|
||||
*/
|
||||
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
require(b <= a, "SafeMath: subtraction overflow");
|
||||
return a - b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the multiplication of two unsigned integers, reverting on
|
||||
* overflow.
|
||||
*
|
||||
* Counterpart to Solidity's `*` operator.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - Multiplication cannot overflow.
|
||||
*/
|
||||
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
if (a == 0) return 0;
|
||||
uint256 c = a * b;
|
||||
require(c / a == b, "SafeMath: multiplication overflow");
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the integer division of two unsigned integers, reverting on
|
||||
* division by zero. The result is rounded towards zero.
|
||||
*
|
||||
* Counterpart to Solidity's `/` operator. Note: this function uses a
|
||||
* `revert` opcode (which leaves remaining gas untouched) while Solidity
|
||||
* uses an invalid opcode to revert (consuming all remaining gas).
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - The divisor cannot be zero.
|
||||
*/
|
||||
function div(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
require(b > 0, "SafeMath: division by zero");
|
||||
return a / b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
|
||||
* reverting when dividing by zero.
|
||||
*
|
||||
* Counterpart to Solidity's `%` operator. This function uses a `revert`
|
||||
* opcode (which leaves remaining gas untouched) while Solidity uses an
|
||||
* invalid opcode to revert (consuming all remaining gas).
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - The divisor cannot be zero.
|
||||
*/
|
||||
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
require(b > 0, "SafeMath: modulo by zero");
|
||||
return a % b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
|
||||
* overflow (when the result is negative).
|
||||
*
|
||||
* CAUTION: This function is deprecated because it requires allocating memory for the error
|
||||
* message unnecessarily. For custom revert reasons use {trySub}.
|
||||
*
|
||||
* Counterpart to Solidity's `-` operator.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - Subtraction cannot overflow.
|
||||
*/
|
||||
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
|
||||
require(b <= a, errorMessage);
|
||||
return a - b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
|
||||
* division by zero. The result is rounded towards zero.
|
||||
*
|
||||
* CAUTION: This function is deprecated because it requires allocating memory for the error
|
||||
* message unnecessarily. For custom revert reasons use {tryDiv}.
|
||||
*
|
||||
* Counterpart to Solidity's `/` operator. Note: this function uses a
|
||||
* `revert` opcode (which leaves remaining gas untouched) while Solidity
|
||||
* uses an invalid opcode to revert (consuming all remaining gas).
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - The divisor cannot be zero.
|
||||
*/
|
||||
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
|
||||
require(b > 0, errorMessage);
|
||||
return a / b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
|
||||
* reverting with custom message when dividing by zero.
|
||||
*
|
||||
* CAUTION: This function is deprecated because it requires allocating memory for the error
|
||||
* message unnecessarily. For custom revert reasons use {tryMod}.
|
||||
*
|
||||
* Counterpart to Solidity's `%` operator. This function uses a `revert`
|
||||
* opcode (which leaves remaining gas untouched) while Solidity uses an
|
||||
* invalid opcode to revert (consuming all remaining gas).
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - The divisor cannot be zero.
|
||||
*/
|
||||
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
|
||||
require(b > 0, errorMessage);
|
||||
return a % b;
|
||||
}
|
||||
}
|
||||
|
||||
contract DSMath {
|
||||
uint constant WAD = 10 ** 18;
|
||||
uint constant RAY = 10 ** 27;
|
||||
|
||||
function add(uint x, uint y) internal pure returns (uint z) {
|
||||
z = SafeMath.add(x, y);
|
||||
}
|
||||
|
||||
function sub(uint x, uint y) internal virtual pure returns (uint z) {
|
||||
z = SafeMath.sub(x, y);
|
||||
}
|
||||
|
||||
function mul(uint x, uint y) internal pure returns (uint z) {
|
||||
z = SafeMath.mul(x, y);
|
||||
}
|
||||
|
||||
function div(uint x, uint y) internal pure returns (uint z) {
|
||||
z = SafeMath.div(x, y);
|
||||
}
|
||||
|
||||
function wmul(uint x, uint y) internal pure returns (uint z) {
|
||||
z = SafeMath.add(SafeMath.mul(x, y), WAD / 2) / WAD;
|
||||
}
|
||||
|
||||
function wdiv(uint x, uint y) internal pure returns (uint z) {
|
||||
z = SafeMath.add(SafeMath.mul(x, WAD), y / 2) / y;
|
||||
}
|
||||
|
||||
function rdiv(uint x, uint y) internal pure returns (uint z) {
|
||||
z = SafeMath.add(SafeMath.mul(x, RAY), y / 2) / y;
|
||||
}
|
||||
|
||||
function rmul(uint x, uint y) internal pure returns (uint z) {
|
||||
z = SafeMath.add(SafeMath.mul(x, y), RAY / 2) / RAY;
|
||||
}
|
||||
|
||||
function toInt(uint x) internal pure returns (int y) {
|
||||
y = int(x);
|
||||
require(y >= 0, "int-overflow");
|
||||
}
|
||||
|
||||
function toRad(uint wad) internal pure returns (uint rad) {
|
||||
rad = mul(wad, 10 ** 27);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
abstract contract Basic is DSMath, Stores {
|
||||
|
||||
function convert18ToDec(uint _dec, uint256 _amt) internal pure returns (uint256 amt) {
|
||||
amt = (_amt / 10 ** (18 - _dec));
|
||||
}
|
||||
|
||||
function convertTo18(uint _dec, uint256 _amt) internal pure returns (uint256 amt) {
|
||||
amt = mul(_amt, 10 ** (18 - _dec));
|
||||
}
|
||||
|
||||
function getTokenBal(TokenInterface token) internal view returns(uint _amt) {
|
||||
_amt = address(token) == ethAddr ? address(this).balance : token.balanceOf(address(this));
|
||||
}
|
||||
|
||||
function getTokensDec(TokenInterface buyAddr, TokenInterface sellAddr) internal view returns(uint buyDec, uint sellDec) {
|
||||
buyDec = address(buyAddr) == ethAddr ? 18 : buyAddr.decimals();
|
||||
sellDec = address(sellAddr) == ethAddr ? 18 : sellAddr.decimals();
|
||||
}
|
||||
|
||||
function encodeEvent(string memory eventName, bytes memory eventParam) internal pure returns (bytes memory) {
|
||||
return abi.encode(eventName, eventParam);
|
||||
}
|
||||
|
||||
function changeEthAddress(address buy, address sell) internal pure returns(TokenInterface _buy, TokenInterface _sell){
|
||||
_buy = buy == ethAddr ? TokenInterface(wethAddr) : TokenInterface(buy);
|
||||
_sell = sell == ethAddr ? TokenInterface(wethAddr) : TokenInterface(sell);
|
||||
}
|
||||
|
||||
function convertEthToWeth(bool isEth, TokenInterface token, uint amount) internal {
|
||||
if(isEth) token.deposit{value: amount}();
|
||||
}
|
||||
|
||||
function convertWethToEth(bool isEth, TokenInterface token, uint amount) internal {
|
||||
if(isEth) {
|
||||
token.approve(address(token), amount);
|
||||
token.withdraw(amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface RootChainManagerInterface {
|
||||
function rootToChildToken(address user) external view returns(address);
|
||||
function depositEtherFor(address user) external payable;
|
||||
function depositFor(
|
||||
address user,
|
||||
address rootToken,
|
||||
bytes calldata depositData
|
||||
) external;
|
||||
function exit(bytes calldata inputData) external;
|
||||
}
|
||||
|
||||
interface DepositManagerProxyInterface {
|
||||
function depositERC20ForUser(
|
||||
address _token,
|
||||
address _user,
|
||||
uint256 _amount
|
||||
) external;
|
||||
}
|
||||
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
||||
/**
|
||||
* @dev Polygon POS Bridge ERC20 Predicate
|
||||
*/
|
||||
address internal constant erc20Predicate = 0x40ec5B33f54e0E8A33A975908C5BA1c14e5BbbDf;
|
||||
|
||||
/**
|
||||
* @dev Polygon POS Bridge Manager
|
||||
*/
|
||||
RootChainManagerInterface internal constant migrator = RootChainManagerInterface(0xA0c68C638235ee32657e8f720a23ceC1bFc77C77);
|
||||
|
||||
/**
|
||||
* @dev Polygon Plasma Bridge Manager
|
||||
*/
|
||||
DepositManagerProxyInterface internal constant migratorPlasma = DepositManagerProxyInterface(0x401F6c983eA34274ec46f84D70b31C151321188b);
|
||||
}
|
||||
|
||||
contract Events {
|
||||
event LogDeposit(
|
||||
address targetDsa,
|
||||
address token,
|
||||
uint256 amt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
event LogWithdraw(bytes proof);
|
||||
}
|
||||
|
||||
|
||||
abstract contract PolygonBridgeResolver is Events, Helpers {
|
||||
/**
|
||||
* @dev Deposit assets to the bridge.
|
||||
* @notice Deposit assets to the bridge.
|
||||
* @param targetDsa The address to receive the token on Polygon
|
||||
* @param token The address of the token to deposit. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param amt The amount of tokens to deposit. (For max: `uint256(-1)`)
|
||||
* @param getId ID to retrieve amt.
|
||||
* @param setId ID stores the amount of tokens deposit.
|
||||
*/
|
||||
function deposit(
|
||||
address targetDsa,
|
||||
address token,
|
||||
uint256 amt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) external payable {
|
||||
uint _amt = getUint(getId, amt);
|
||||
|
||||
if (token == ethAddr) {
|
||||
_amt = _amt == uint(-1) ? address(this).balance : _amt;
|
||||
migrator.depositEtherFor{value: _amt}(targetDsa);
|
||||
} else {
|
||||
TokenInterface _token = TokenInterface(token);
|
||||
_amt = _amt == uint(-1) ? _token.balanceOf(address(this)) : _amt;
|
||||
if (migrator.rootToChildToken(token) != address(0)) {
|
||||
_token.approve(erc20Predicate, _amt);
|
||||
migrator.depositFor(targetDsa, token, abi.encode(_amt));
|
||||
} else {
|
||||
_token.approve(address(migratorPlasma), _amt);
|
||||
migratorPlasma.depositERC20ForUser(token, targetDsa, _amt);
|
||||
}
|
||||
}
|
||||
|
||||
setUint(setId, _amt);
|
||||
emit LogDeposit(targetDsa, token, _amt, getId, setId);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectPolygonBridge is PolygonBridgeResolver {
|
||||
/**
|
||||
* @dev Connector Details
|
||||
*/
|
||||
function connectorID() public pure returns(uint _type, uint _id) {
|
||||
(_type, _id) = (1, 100);
|
||||
}
|
||||
|
||||
string public constant name = "Polygon-Bridge-v1.1";
|
||||
}
|
119
contracts/mainnet/mapping/StakeERC20.sol
Normal file
119
contracts/mainnet/mapping/StakeERC20.sol
Normal file
|
@ -0,0 +1,119 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
interface ConnectorsInterface {
|
||||
function chief(address) external view returns (bool);
|
||||
}
|
||||
|
||||
interface IndexInterface {
|
||||
function master() external view returns (address);
|
||||
}
|
||||
|
||||
contract BytesHelper {
|
||||
/**
|
||||
* @dev Convert String to bytes32.
|
||||
*/
|
||||
function stringToBytes32(string memory str) internal pure returns (bytes32 result) {
|
||||
require(bytes(str).length != 0, "String-Empty");
|
||||
// solium-disable-next-line security/no-inline-assembly
|
||||
assembly {
|
||||
result := mload(add(str, 32))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Convert bytes32 to String.
|
||||
*/
|
||||
function bytes32ToString(bytes32 _bytes32) internal pure returns (string memory) {
|
||||
bytes32 _temp;
|
||||
uint count;
|
||||
for (uint256 i; i < 32; i++) {
|
||||
_temp = _bytes32[i];
|
||||
if( _temp != bytes32(0)) {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
bytes memory bytesArray = new bytes(count);
|
||||
for (uint256 i; i < count; i++) {
|
||||
bytesArray[i] = (_bytes32[i]);
|
||||
}
|
||||
return (string(bytesArray));
|
||||
}
|
||||
}
|
||||
|
||||
contract Helpers is BytesHelper {
|
||||
address public constant connectorsV2 = 0x97b0B3A8bDeFE8cB9563a3c610019Ad10DB8aD11;
|
||||
address public constant instaIndex = 0x2971AdFa57b20E5a416aE5a708A8655A9c74f723;
|
||||
|
||||
mapping (bytes32 => StakingData) public stakingMapping;
|
||||
|
||||
struct StakingData {
|
||||
address stakingPool;
|
||||
address stakingToken;
|
||||
address rewardToken;
|
||||
}
|
||||
|
||||
event LogAddStakingMapping(
|
||||
string stakingName,
|
||||
bytes32 stakingType,
|
||||
address stakingAddress,
|
||||
address stakingToken,
|
||||
address rewardToken
|
||||
);
|
||||
event LogRemoveStakingMapping(
|
||||
string stakingName,
|
||||
bytes32 stakingType,
|
||||
address stakingAddress,
|
||||
address stakingToken,
|
||||
address rewardToken
|
||||
);
|
||||
|
||||
modifier isChief virtual {
|
||||
require(
|
||||
ConnectorsInterface(connectorsV2).chief(msg.sender) ||
|
||||
IndexInterface(instaIndex).master() == msg.sender, "not-Chief");
|
||||
_;
|
||||
}
|
||||
|
||||
function addStakingMapping(
|
||||
string memory stakingName,
|
||||
address stakingAddress,
|
||||
address stakingToken,
|
||||
address rewardToken
|
||||
) public isChief {
|
||||
require(stakingAddress != address(0), "stakingAddress-not-vaild");
|
||||
require(stakingToken != address(0), "stakingToken-not-vaild");
|
||||
require(rewardToken != address(0), "rewardToken-not-vaild");
|
||||
require(bytes(stakingName).length <= 32, "Length-exceeds");
|
||||
bytes32 stakeType = stringToBytes32(stakingName);
|
||||
require(stakingMapping[stakeType].stakingPool == address(0), "StakingPool-already-added");
|
||||
require(stakingMapping[stakeType].stakingToken == address(0), "StakingToken-already-added");
|
||||
require(stakingMapping[stakeType].rewardToken == address(0), "rewardToken-already-added");
|
||||
|
||||
stakingMapping[stakeType] = StakingData(
|
||||
stakingAddress,
|
||||
stakingToken,
|
||||
rewardToken
|
||||
);
|
||||
emit LogAddStakingMapping(stakingName, stakeType, stakingAddress, stakingToken, rewardToken);
|
||||
}
|
||||
|
||||
function removeStakingMapping(string memory stakingName, address stakingAddress) public isChief {
|
||||
require(stakingAddress != address(0), "stakingAddress-not-vaild");
|
||||
bytes32 stakeType = stringToBytes32(stakingName);
|
||||
require(stakingMapping[stakeType].stakingPool == stakingAddress, "different-staking-pool");
|
||||
|
||||
emit LogRemoveStakingMapping(
|
||||
stakingName,
|
||||
stakeType,
|
||||
stakingAddress,
|
||||
stakingMapping[stakeType].stakingToken,
|
||||
stakingMapping[stakeType].rewardToken
|
||||
);
|
||||
delete stakingMapping[stakeType];
|
||||
}
|
||||
}
|
||||
|
||||
contract InstaStakingERC20Mapping is Helpers {
|
||||
string constant public name = "Staking-ERC20-Mapping-v1";
|
||||
}
|
|
@ -33,6 +33,11 @@ abstract contract IncentivesResolver is Helpers, Events {
|
|||
|
||||
_amt = incentives.claimRewards(assets, _amt, address(this));
|
||||
|
||||
|
||||
TokenInterface wmatic = TokenInterface(wmaticAddr);
|
||||
uint256 wmaticAmount = wmatic.balanceOf(address(this));
|
||||
convertWmaticToMatic(wmaticAmount > 0, wmatic, wmaticAmount);
|
||||
|
||||
setUint(setId, _amt);
|
||||
|
||||
_eventName = "LogClaimed(address[],uint256,uint256,uint256)";
|
||||
|
|
|
@ -1,17 +1,27 @@
|
|||
{
|
||||
"1" : {
|
||||
"1INCH-A": "0x6C7256cf7C003dD85683339F75DdE9971f98f2FD",
|
||||
"1INCH-A": "0x2A6d6d4EE84015F7D64B4d1F66a409bA3f2BAC00",
|
||||
"1INCH-B": "0x36880391afb430e99d43fe94217446b56d4f2c5b",
|
||||
"AAVE-V1-A": "0x127d8cD0E2b2E0366D522DeA53A787bfE9002C14",
|
||||
"AAVE-V2-A": "0x497Bc53507DF17e60F731e9534cff74E8BC9DBb8",
|
||||
"AUTHORITY-A": "0x6CE3e607C808b4f4C26B7F6aDAeB619e49CAbb25",
|
||||
"AUTHORITY-A": "0x351Bb32e90C35647Df7a584f3c1a3A0c38F31c68",
|
||||
"BASIC-A": "0x9926955e0Dd681Dc303370C52f4Ad0a4dd061687",
|
||||
"COMP-A": "0xB446e325D44C52b93eC122Bf76301f235f90B9c9",
|
||||
"COMPOUND-A": "0x911F4e4e762AeFA6F2Fc1b24e6B1A928200a88a8",
|
||||
"MAKERDAO-A": "0x839c2D3aDe63DF5b0b8F3E57D5e145057Ab41556",
|
||||
"MAKERDAO-A": "0x29AA7b765008b5dDbD687413B7F0D6E9d349F765",
|
||||
"UNISWAP-A": "0xA4BF319968986D2352FA1c550D781bBFCCE3FcaB",
|
||||
"POLYGON-BRIDGE-A": "0x697860CeE594c577F18f71cAf3d8B68D913c7366",
|
||||
"POLYGON-BRIDGE-A": "0x1b79B302132370B434fb7807b36CB72FB0510aD5",
|
||||
"AAVE-CLAIM-A": "0x611C1FA59Aa1d6352c4C8bD44882063c6aEE85E0",
|
||||
"AAVE-STAKE-A": "0xf73c94402bc24148b744083ed02654eec2c37d5b"
|
||||
"AAVE-STAKE-A": "0xf73c94402bc24148b744083ed02654eec2c37d5b",
|
||||
"G-UNISWAP-A": "0x2fca923c7535083f25f761dcf289d7d81f024dda",
|
||||
"INST-STAKING-A": "0x37a63939e128d284e0eae5d3e517aad44f5204d4",
|
||||
"AAVE-V2-IMPORT-B": "0x6fe05374924830B6aC98849f75A3D5766E51Ef10",
|
||||
"COMPOUND-IMPORT-B": "0xdA101870ca6136539628F28041E1B55baf4EB6C0",
|
||||
"INSTAPOOL-A": "0x5806Af7AB22E2916fA582Ff05731Bf7C682387B2",
|
||||
"MAKERDAO-CLAIM-A": "0x2f8cBE650af98602a215b6482F2aD60893C5A4E8",
|
||||
"WETH-A": "0x22075fa719eFb02Ca3cF298AFa9C974B7465E5D3",
|
||||
"REFINANCE-A": "0x9eA34bE6dA51aa9F6408FeA79c946FDCFA424442"
|
||||
"INST-A": "0x52C2C4a0db049255fF345EB9D3Fb1f555b7a924A"
|
||||
},
|
||||
"137" : {
|
||||
"AAVE-V2-A": "0xE84d8010Afc3663919F44685cB53ED88866da3eE",
|
||||
|
@ -19,4 +29,5 @@
|
|||
"BASIC-A": "0x1cAF5EC802ca602E98139AD96A8f2B7BC524264E",
|
||||
"AAVE-CLAIM-A": "0xC7Cb1dE2721BFC0E0DA1b9D526bCdC54eF1C0eFC",
|
||||
"PARASWAP-A": "0xFb3a1D56eD56F046721B9aCa749895100754578b"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ require("@nomiclabs/hardhat-waffle");
|
|||
require("@nomiclabs/hardhat-ethers");
|
||||
require("@tenderly/hardhat-tenderly");
|
||||
require("@nomiclabs/hardhat-etherscan");
|
||||
require("@nomiclabs/hardhat-web3")
|
||||
require("@nomiclabs/hardhat-web3");
|
||||
require("hardhat-deploy");
|
||||
require("hardhat-deploy-ethers");
|
||||
require("dotenv").config();
|
||||
|
@ -12,6 +12,10 @@ const { utils } = require("ethers");
|
|||
const PRIVATE_KEY = process.env.PRIVATE_KEY;
|
||||
const ALCHEMY_ID = process.env.ALCHEMY_ID;
|
||||
|
||||
if (!process.env.ALCHEMY_ID) {
|
||||
throw new Error("ENV Variable ALCHEMY_ID not set!");
|
||||
}
|
||||
|
||||
/**
|
||||
* @type import('hardhat/config').HardhatUserConfig
|
||||
*/
|
||||
|
@ -19,16 +23,16 @@ module.exports = {
|
|||
solidity: {
|
||||
compilers: [
|
||||
{
|
||||
version: "0.7.6"
|
||||
version: "0.7.6",
|
||||
},
|
||||
{
|
||||
version: "0.6.0"
|
||||
version: "0.6.0",
|
||||
},
|
||||
{
|
||||
version: "0.6.2"
|
||||
version: "0.6.2",
|
||||
},
|
||||
{
|
||||
version: "0.6.5"
|
||||
version: "0.6.5",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -42,27 +46,30 @@ module.exports = {
|
|||
url: `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_ID}`,
|
||||
accounts: [`0x${PRIVATE_KEY}`],
|
||||
timeout: 150000,
|
||||
gasPrice: parseInt(utils.parseUnits("132", "gwei"))
|
||||
gasPrice: parseInt(utils.parseUnits("34", "gwei")),
|
||||
},
|
||||
hardhat: {
|
||||
forking: {
|
||||
url: `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_ID}`,
|
||||
blockNumber: 12433781,
|
||||
blockNumber: 12696000,
|
||||
},
|
||||
blockGasLimit: 12000000
|
||||
blockGasLimit: 12000000,
|
||||
},
|
||||
matic: {
|
||||
url: "https://rpc-mainnet.maticvigil.com/",
|
||||
accounts: [`0x${PRIVATE_KEY}`],
|
||||
timeout: 150000,
|
||||
gasPrice: parseInt(utils.parseUnits("1", "gwei"))
|
||||
gasPrice: parseInt(utils.parseUnits("1", "gwei")),
|
||||
},
|
||||
},
|
||||
etherscan: {
|
||||
apiKey: process.env.ETHERSCAN_API_KEY
|
||||
apiKey: process.env.ETHERSCAN_API_KEY,
|
||||
},
|
||||
tenderly: {
|
||||
project: process.env.TENDERLY_PROJECT,
|
||||
username: process.env.TENDERLY_USERNAME
|
||||
username: process.env.TENDERLY_USERNAME,
|
||||
},
|
||||
mocha: {
|
||||
timeout: 100 * 1000,
|
||||
},
|
||||
};
|
||||
|
|
8477
package-lock.json
generated
8477
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
78
scripts/addLiquidity.js
Normal file
78
scripts/addLiquidity.js
Normal file
|
@ -0,0 +1,78 @@
|
|||
const { ethers } = require("hardhat");
|
||||
const impersonateAccounts = require("./impersonate");
|
||||
|
||||
const mineTx = async (tx) => {
|
||||
await (await tx).wait();
|
||||
};
|
||||
|
||||
const tokenMapping = {
|
||||
usdc: {
|
||||
impersonateSigner: "0xfcb19e6a322b27c06842a71e8c725399f049ae3a",
|
||||
address: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
|
||||
abi: [
|
||||
"function mint(address _to, uint256 _amount) external returns (bool);",
|
||||
],
|
||||
process: async function(owner, to, amt) {
|
||||
const contract = new ethers.Contract(this.address, this.abi, owner);
|
||||
|
||||
await mineTx(contract.mint(to, amt));
|
||||
},
|
||||
},
|
||||
dai: {
|
||||
impersonateSigner: "0x47ac0fb4f2d84898e4d9e7b4dab3c24507a6d503",
|
||||
abi: ["function transfer(address to, uint value)"],
|
||||
address: "0x6b175474e89094c44da98b954eedeac495271d0f",
|
||||
process: async function(owner, to, amt) {
|
||||
const contract = new ethers.Contract(this.address, this.abi, owner);
|
||||
await mineTx(contract.transfer(to, amt));
|
||||
},
|
||||
},
|
||||
usdt: {
|
||||
impersonateSigner: "0xc6cde7c39eb2f0f0095f41570af89efc2c1ea828",
|
||||
address: "0xdac17f958d2ee523a2206206994597c13d831ec7",
|
||||
abi: [
|
||||
"function issue(uint amount)",
|
||||
"function transfer(address to, uint value)",
|
||||
],
|
||||
process: async function(owner, address, amt) {
|
||||
const contract = new ethers.Contract(this.address, this.abi, owner);
|
||||
|
||||
await mineTx(contract.issue(amt));
|
||||
await mineTx(contract.transfer(address, amt));
|
||||
},
|
||||
},
|
||||
wbtc: {
|
||||
impersonateSigner: "0xCA06411bd7a7296d7dbdd0050DFc846E95fEBEB7",
|
||||
address: "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599",
|
||||
abi: ["function mint(address _to, uint256 _amount) public returns (bool)"],
|
||||
process: async function(owner, address, amt) {
|
||||
const contract = new ethers.Contract(this.address, this.abi, owner);
|
||||
await mineTx(contract.mint(address, amt));
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = async (tokenName, address, amt) => {
|
||||
const [signer] = await ethers.getSigners();
|
||||
tokenName = tokenName.toLowerCase();
|
||||
if (!tokenMapping[tokenName]) {
|
||||
throw new Error(
|
||||
"Add liquidity doesn't support the following token: ",
|
||||
tokenName
|
||||
);
|
||||
}
|
||||
|
||||
const token = tokenMapping[tokenName];
|
||||
|
||||
const [impersonatedSigner] = await impersonateAccounts([
|
||||
token.impersonateSigner,
|
||||
]);
|
||||
|
||||
// send 1 eth to cover any tx costs.
|
||||
await signer.sendTransaction({
|
||||
to: impersonatedSigner.address,
|
||||
value: ethers.utils.parseEther("1"),
|
||||
});
|
||||
|
||||
await token.process(impersonatedSigner, address, amt);
|
||||
};
|
1
scripts/constant/abi/connectors/instapool.json
Normal file
1
scripts/constant/abi/connectors/instapool.json
Normal file
|
@ -0,0 +1 @@
|
|||
[{"type":"event","name":"LogFlashBorrow","inputs":[{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"tokenAmt","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"LogFlashMultiBorrow","inputs":[{"type":"address[]","name":"token","internalType":"address[]","indexed":false},{"type":"uint256[]","name":"tokenAmts","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"event","name":"LogFlashMultiPayback","inputs":[{"type":"address[]","name":"token","internalType":"address[]","indexed":false},{"type":"uint256[]","name":"tokenAmts","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"event","name":"LogFlashPayback","inputs":[{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"tokenAmt","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"payable","outputs":[{"type":"string","name":"_eventName","internalType":"string"},{"type":"bytes","name":"_eventParam","internalType":"bytes"}],"name":"flashBorrowAndCast","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"amt","internalType":"uint256"},{"type":"uint256","name":"route","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"string","name":"_eventName","internalType":"string"},{"type":"bytes","name":"_eventParam","internalType":"bytes"}],"name":"flashMultiBorrowAndCast","inputs":[{"type":"address[]","name":"tokens","internalType":"address[]"},{"type":"uint256[]","name":"amts","internalType":"uint256[]"},{"type":"uint256","name":"route","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"string","name":"_eventName","internalType":"string"},{"type":"bytes","name":"_eventParam","internalType":"bytes"}],"name":"flashMultiPayback","inputs":[{"type":"address[]","name":"tokens","internalType":"address[]"},{"type":"uint256[]","name":"amts","internalType":"uint256[]"},{"type":"uint256[]","name":"getId","internalType":"uint256[]"},{"type":"uint256[]","name":"setId","internalType":"uint256[]"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"string","name":"_eventName","internalType":"string"},{"type":"bytes","name":"_eventParam","internalType":"bytes"}],"name":"flashPayback","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"amt","internalType":"uint256"},{"type":"uint256","name":"getId","internalType":"uint256"},{"type":"uint256","name":"setId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract InstaFlashV2Interface"}],"name":"instaPool","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]}]
|
|
@ -7,6 +7,7 @@ module.exports = {
|
|||
"Basic-v1": require("./abi/connectors/basic.json"),
|
||||
basic: require("./abi/connectors/basic.json"),
|
||||
auth: require("./abi/connectors/auth.json"),
|
||||
"INSTAPOOL-A": require("./abi/connectors/instapool.json"),
|
||||
},
|
||||
basic: {
|
||||
erc20: require("./abi/basics/erc20.json"),
|
||||
|
|
|
@ -2,6 +2,7 @@ module.exports = {
|
|||
connectors: {
|
||||
basic: "0xe5398f279175962E56fE4c5E0b62dc7208EF36c6",
|
||||
auth: "0xd1aff9f2acf800c876c409100d6f39aea93fc3d9",
|
||||
"INSTAPOOL-A": "0x5806af7ab22e2916fa582ff05731bf7c682387b2",
|
||||
},
|
||||
core: {
|
||||
connectorsV2: "0x97b0B3A8bDeFE8cB9563a3c610019Ad10DB8aD11",
|
||||
|
|
16
scripts/encodeFlashcastData.js
Normal file
16
scripts/encodeFlashcastData.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
const abis = require("./constant/abis");
|
||||
const addresses = require("./constant/addresses");
|
||||
const { web3 } = hre;
|
||||
|
||||
const encodeSpells = require("./encodeSpells.js")
|
||||
|
||||
|
||||
module.exports = function (spells) {
|
||||
const encodeSpellsData = encodeSpells(spells);
|
||||
const targetType = "string[]";
|
||||
let argTypes = [targetType, "bytes[]"];
|
||||
return web3.eth.abi.encodeParameters(argTypes, [
|
||||
encodeSpellsData[0],
|
||||
encodeSpellsData[1],
|
||||
]);
|
||||
};
|
|
@ -1,23 +1,25 @@
|
|||
const hre = require("hardhat");
|
||||
const { ethers, waffle } = hre;
|
||||
const { ethers } = hre;
|
||||
const addresses = require("./constant/addresses");
|
||||
const abis = require("./constant/abis");
|
||||
const { provider, deployContract } = waffle
|
||||
|
||||
module.exports = async function() {
|
||||
const [_, __, ___, wallet3] = await ethers.getSigners();
|
||||
const instaIndex = new ethers.Contract(
|
||||
addresses.core.instaIndex,
|
||||
abis.core.instaIndex,
|
||||
wallet3
|
||||
);
|
||||
|
||||
module.exports = async function () {
|
||||
const instaIndex = await ethers.getContractAt(abis.core.instaIndex, addresses.core.instaIndex)
|
||||
const masterAddress = await instaIndex.master(); // TODO: make it constant?
|
||||
await hre.network.provider.request({
|
||||
method: "hardhat_impersonateAccount",
|
||||
params: [masterAddress],
|
||||
});
|
||||
await wallet3.sendTransaction({
|
||||
to: masterAddress,
|
||||
value: ethers.utils.parseEther("10"),
|
||||
});
|
||||
|
||||
const masterAddress = await instaIndex.master(); // TODO: make it constant?
|
||||
await hre.network.provider.request({
|
||||
method: "hardhat_impersonateAccount",
|
||||
params: [ masterAddress]
|
||||
})
|
||||
const [wallet0, wallet1, wallet2, wallet3] = await ethers.getSigners()
|
||||
await wallet3.sendTransaction({
|
||||
to: masterAddress,
|
||||
value: ethers.utils.parseEther("10")
|
||||
});
|
||||
|
||||
return await ethers.getSigner(masterAddress);
|
||||
return await ethers.getSigner(masterAddress);
|
||||
};
|
||||
|
|
15
scripts/impersonate.js
Normal file
15
scripts/impersonate.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
const { ethers, network } = require("hardhat");
|
||||
|
||||
module.exports = async (accounts) => {
|
||||
const signers = [];
|
||||
for (const account of accounts) {
|
||||
await network.provider.request({
|
||||
method: "hardhat_impersonateAccount",
|
||||
params: [account],
|
||||
});
|
||||
|
||||
signers.push(await ethers.getSigner(account));
|
||||
}
|
||||
|
||||
return signers;
|
||||
};
|
151
test/aave/v1.test.js
Normal file
151
test/aave/v1.test.js
Normal file
|
@ -0,0 +1,151 @@
|
|||
const { expect } = require("chai");
|
||||
const hre = require("hardhat");
|
||||
const abis = require("../../scripts/constant/abis");
|
||||
const addresses = require("../../scripts/constant/addresses");
|
||||
const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector");
|
||||
const getMasterSigner = require("../../scripts/getMasterSigner");
|
||||
const buildDSAv2 = require("../../scripts/buildDSAv2");
|
||||
const ConnectV2AaveV1 = require("../../artifacts/contracts/mainnet/connectors/aave/v1/main.sol/ConnectV2AaveV1.json");
|
||||
const { parseEther } = require("@ethersproject/units");
|
||||
const encodeSpells = require("../../scripts/encodeSpells");
|
||||
const tokens = require("../../scripts/constant/tokens");
|
||||
const constants = require("../../scripts/constant/constant");
|
||||
const addLiquidity = require("../../scripts/addLiquidity");
|
||||
const { ethers } = hre;
|
||||
|
||||
describe("Aave V1", function() {
|
||||
const connectorName = "AAVEV1-TEST-A";
|
||||
|
||||
let wallet0, wallet1;
|
||||
let dsaWallet0;
|
||||
let instaConnectorsV2;
|
||||
let connector;
|
||||
let masterSigner;
|
||||
|
||||
before(async () => {
|
||||
[wallet0, wallet1] = await ethers.getSigners();
|
||||
masterSigner = await getMasterSigner();
|
||||
instaConnectorsV2 = await ethers.getContractAt(
|
||||
abis.core.connectorsV2,
|
||||
addresses.core.connectorsV2
|
||||
);
|
||||
connector = await deployAndEnableConnector({
|
||||
connectorName,
|
||||
contractArtifact: ConnectV2AaveV1,
|
||||
signer: masterSigner,
|
||||
connectors: instaConnectorsV2,
|
||||
});
|
||||
console.log("Connector address", connector.address);
|
||||
});
|
||||
|
||||
it("should have contracts deployed", async () => {
|
||||
expect(!!instaConnectorsV2.address).to.be.true;
|
||||
expect(!!connector.address).to.be.true;
|
||||
expect(!!masterSigner.address).to.be.true;
|
||||
});
|
||||
|
||||
describe("DSA wallet setup", function() {
|
||||
it("Should build DSA v2", async function() {
|
||||
dsaWallet0 = await buildDSAv2(wallet0.address);
|
||||
expect(!!dsaWallet0.address).to.be.true;
|
||||
});
|
||||
|
||||
it("Deposit ETH into DSA wallet", async function() {
|
||||
await wallet0.sendTransaction({
|
||||
to: dsaWallet0.address,
|
||||
value: parseEther("10"),
|
||||
});
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
|
||||
parseEther("10")
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Main", function() {
|
||||
it("should deposit ETH in Aave V1", async function() {
|
||||
const amt = parseEther("1");
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "deposit",
|
||||
args: [tokens.eth.address, amt, 0, 0],
|
||||
},
|
||||
];
|
||||
|
||||
const tx = await dsaWallet0
|
||||
.connect(wallet0)
|
||||
.cast(...encodeSpells(spells), wallet1.address);
|
||||
|
||||
await tx.wait();
|
||||
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.eq(
|
||||
parseEther("9")
|
||||
);
|
||||
});
|
||||
|
||||
it("Should borrow and payback DAI from Aave V1", async function() {
|
||||
const amt = parseEther("100"); // 100 DAI
|
||||
|
||||
// add a little amount of dai to cover any shortfalls
|
||||
await addLiquidity("dai", dsaWallet0.address, parseEther("1"));
|
||||
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "borrow",
|
||||
args: [tokens.dai.address, amt, 0, 0],
|
||||
},
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "payback",
|
||||
// FIXME: we need to pass max_value because of roundoff/shortfall errors
|
||||
args: [tokens.dai.address, constants.max_value, 0, 0],
|
||||
},
|
||||
];
|
||||
|
||||
const tx = await dsaWallet0
|
||||
.connect(wallet0)
|
||||
.cast(...encodeSpells(spells), wallet1.address);
|
||||
await tx.wait();
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
|
||||
ethers.utils.parseEther("9")
|
||||
);
|
||||
});
|
||||
|
||||
it("Should deposit all ETH in Aave V1", async function() {
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "deposit",
|
||||
args: [tokens.eth.address, constants.max_value, 0, 0],
|
||||
},
|
||||
];
|
||||
|
||||
const tx = await dsaWallet0
|
||||
.connect(wallet0)
|
||||
.cast(...encodeSpells(spells), wallet1.address);
|
||||
await tx.wait();
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
|
||||
ethers.utils.parseEther("0")
|
||||
);
|
||||
});
|
||||
|
||||
it("Should withdraw all ETH from Aave V1", async function() {
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "withdraw",
|
||||
args: [tokens.eth.address, constants.max_value, 0, 0],
|
||||
},
|
||||
];
|
||||
|
||||
const tx = await dsaWallet0
|
||||
.connect(wallet0)
|
||||
.cast(...encodeSpells(spells), wallet1.address);
|
||||
await tx.wait();
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
|
||||
ethers.utils.parseEther("10")
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
214
test/aave/v2.test.js
Normal file
214
test/aave/v2.test.js
Normal file
|
@ -0,0 +1,214 @@
|
|||
const { expect } = require("chai");
|
||||
const hre = require("hardhat");
|
||||
const abis = require("../../scripts/constant/abis");
|
||||
const addresses = require("../../scripts/constant/addresses");
|
||||
const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector");
|
||||
const getMasterSigner = require("../../scripts/getMasterSigner");
|
||||
const buildDSAv2 = require("../../scripts/buildDSAv2");
|
||||
const ConnectV2AaveV2 = require("../../artifacts/contracts/mainnet/connectors/aave/v2/main.sol/ConnectV2AaveV2.json");
|
||||
const { parseEther } = require("@ethersproject/units");
|
||||
const encodeSpells = require("../../scripts/encodeSpells");
|
||||
const tokens = require("../../scripts/constant/tokens");
|
||||
const constants = require("../../scripts/constant/constant");
|
||||
const addLiquidity = require("../../scripts/addLiquidity");
|
||||
const { ethers } = hre;
|
||||
|
||||
describe("Aave V2", function() {
|
||||
const connectorName = "AAVEV2-TEST-A";
|
||||
|
||||
let wallet0, wallet1;
|
||||
let dsaWallet0;
|
||||
let instaConnectorsV2;
|
||||
let connector;
|
||||
let masterSigner;
|
||||
|
||||
before(async () => {
|
||||
[wallet0, wallet1] = await ethers.getSigners();
|
||||
masterSigner = await getMasterSigner();
|
||||
instaConnectorsV2 = await ethers.getContractAt(
|
||||
abis.core.connectorsV2,
|
||||
addresses.core.connectorsV2
|
||||
);
|
||||
connector = await deployAndEnableConnector({
|
||||
connectorName,
|
||||
contractArtifact: ConnectV2AaveV2,
|
||||
signer: masterSigner,
|
||||
connectors: instaConnectorsV2,
|
||||
});
|
||||
console.log("Connector address", connector.address);
|
||||
});
|
||||
|
||||
it("should have contracts deployed", async () => {
|
||||
expect(!!instaConnectorsV2.address).to.be.true;
|
||||
expect(!!connector.address).to.be.true;
|
||||
expect(!!masterSigner.address).to.be.true;
|
||||
});
|
||||
|
||||
describe("DSA wallet setup", function() {
|
||||
it("Should build DSA v2", async function() {
|
||||
dsaWallet0 = await buildDSAv2(wallet0.address);
|
||||
expect(!!dsaWallet0.address).to.be.true;
|
||||
});
|
||||
|
||||
it("Deposit ETH into DSA wallet", async function() {
|
||||
await wallet0.sendTransaction({
|
||||
to: dsaWallet0.address,
|
||||
value: parseEther("10"),
|
||||
});
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
|
||||
parseEther("10")
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Main", function() {
|
||||
it("should deposit ETH in Aave V2", async function() {
|
||||
const amt = parseEther("1");
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "deposit",
|
||||
args: [tokens.eth.address, amt, 0, 0],
|
||||
},
|
||||
];
|
||||
|
||||
const tx = await dsaWallet0
|
||||
.connect(wallet0)
|
||||
.cast(...encodeSpells(spells), wallet1.address);
|
||||
|
||||
await tx.wait();
|
||||
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.eq(
|
||||
parseEther("9")
|
||||
);
|
||||
});
|
||||
|
||||
it("Should borrow and payback DAI from Aave V2", async function() {
|
||||
const amt = parseEther("100"); // 100 DAI
|
||||
const setId = "83478237";
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "borrow",
|
||||
args: [tokens.dai.address, amt, 2, 0, setId],
|
||||
},
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "payback",
|
||||
args: [tokens.dai.address, amt, 2, setId, 0],
|
||||
},
|
||||
];
|
||||
|
||||
const tx = await dsaWallet0
|
||||
.connect(wallet0)
|
||||
.cast(...encodeSpells(spells), wallet1.address);
|
||||
await tx.wait();
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
|
||||
ethers.utils.parseEther("9")
|
||||
);
|
||||
});
|
||||
|
||||
it("Should borrow and payback half DAI from Aave V2", async function() {
|
||||
const amt = parseEther("100"); // 100 DAI
|
||||
// const setId = "83478237";
|
||||
await addLiquidity("dai", dsaWallet0.address, parseEther("1"));
|
||||
let spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "borrow",
|
||||
args: [tokens.dai.address, amt, 2, 0, 0],
|
||||
},
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "payback",
|
||||
args: [tokens.dai.address, amt.div(2), 2, 0, 0],
|
||||
},
|
||||
];
|
||||
|
||||
let tx = await dsaWallet0
|
||||
.connect(wallet0)
|
||||
.cast(...encodeSpells(spells), wallet1.address);
|
||||
await tx.wait();
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
|
||||
ethers.utils.parseEther("9")
|
||||
);
|
||||
|
||||
spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "payback",
|
||||
args: [tokens.dai.address, constants.max_value, 2, 0, 0],
|
||||
},
|
||||
];
|
||||
|
||||
tx = await dsaWallet0
|
||||
.connect(wallet0)
|
||||
.cast(...encodeSpells(spells), wallet1.address);
|
||||
await tx.wait();
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
|
||||
ethers.utils.parseEther("9")
|
||||
);
|
||||
});
|
||||
|
||||
it("Should deposit all ETH in Aave V2", async function() {
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "deposit",
|
||||
args: [tokens.eth.address, constants.max_value, 0, 0],
|
||||
},
|
||||
];
|
||||
|
||||
const tx = await dsaWallet0
|
||||
.connect(wallet0)
|
||||
.cast(...encodeSpells(spells), wallet1.address);
|
||||
await tx.wait();
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
|
||||
ethers.utils.parseEther("0")
|
||||
);
|
||||
});
|
||||
|
||||
it("Should withdraw all ETH from Aave V2", async function() {
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "withdraw",
|
||||
args: [tokens.eth.address, constants.max_value, 0, 0],
|
||||
},
|
||||
];
|
||||
|
||||
const tx = await dsaWallet0
|
||||
.connect(wallet0)
|
||||
.cast(...encodeSpells(spells), wallet1.address);
|
||||
await tx.wait();
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
|
||||
ethers.utils.parseEther("10")
|
||||
);
|
||||
});
|
||||
|
||||
it("should deposit and withdraw", async () => {
|
||||
const amt = parseEther("1"); // 1 eth
|
||||
const setId = "834782373";
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "deposit",
|
||||
args: [tokens.eth.address, amt, 0, setId],
|
||||
},
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "withdraw",
|
||||
args: [tokens.eth.address, amt, setId, 0],
|
||||
},
|
||||
];
|
||||
|
||||
const tx = await dsaWallet0
|
||||
.connect(wallet0)
|
||||
.cast(...encodeSpells(spells), wallet1.address);
|
||||
await tx.wait();
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
|
||||
ethers.utils.parseEther("10")
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -124,4 +124,4 @@ describe("Compound", function () {
|
|||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
|
||||
});
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
109
test/instapool/instapool.test.js
Normal file
109
test/instapool/instapool.test.js
Normal file
|
@ -0,0 +1,109 @@
|
|||
const { expect } = require("chai");
|
||||
const hre = require("hardhat");
|
||||
const { web3, deployments, waffle, ethers } = hre;
|
||||
const { provider, deployContract } = waffle
|
||||
|
||||
const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js")
|
||||
const buildDSAv2 = require("../../scripts/buildDSAv2")
|
||||
const encodeSpells = require("../../scripts/encodeSpells.js")
|
||||
const encodeFlashcastData = require("../../scripts/encodeFlashcastData.js")
|
||||
const getMasterSigner = require("../../scripts/getMasterSigner")
|
||||
|
||||
const addresses = require("../../scripts/constant/addresses");
|
||||
const abis = require("../../scripts/constant/abis");
|
||||
const constants = require("../../scripts/constant/constant");
|
||||
const tokens = require("../../scripts/constant/tokens");
|
||||
|
||||
const connectV2CompoundArtifacts = require("../../artifacts/contracts/mainnet/connectors/compound/main.sol/ConnectV2Compound.json")
|
||||
|
||||
describe("Instapool", function () {
|
||||
const connectorName = "COMPOUND-TEST-A"
|
||||
|
||||
let dsaWallet0
|
||||
let masterSigner;
|
||||
let instaConnectorsV2;
|
||||
let connector;
|
||||
|
||||
const wallets = provider.getWallets()
|
||||
const [wallet0, wallet1, wallet2, wallet3] = wallets
|
||||
before(async () => {
|
||||
masterSigner = await getMasterSigner(wallet3)
|
||||
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
|
||||
connector = await deployAndEnableConnector({
|
||||
connectorName,
|
||||
contractArtifact: connectV2CompoundArtifacts,
|
||||
signer: masterSigner,
|
||||
connectors: instaConnectorsV2
|
||||
})
|
||||
console.log("Connector address", connector.address)
|
||||
})
|
||||
|
||||
it("Should have contracts deployed.", async function () {
|
||||
expect(!!instaConnectorsV2.address).to.be.true;
|
||||
expect(!!connector.address).to.be.true;
|
||||
expect(!!masterSigner.address).to.be.true;
|
||||
});
|
||||
|
||||
describe("DSA wallet setup", function () {
|
||||
it("Should build DSA v2", async function () {
|
||||
dsaWallet0 = await buildDSAv2(wallet0.address)
|
||||
expect(!!dsaWallet0.address).to.be.true;
|
||||
});
|
||||
|
||||
it("Deposit ETH into DSA wallet", async function () {
|
||||
await wallet0.sendTransaction({
|
||||
to: dsaWallet0.address,
|
||||
value: ethers.utils.parseEther("10")
|
||||
});
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
|
||||
});
|
||||
});
|
||||
|
||||
describe("Main", function () {
|
||||
|
||||
it("Should take 100 ETH flashloan from Instapool", async function () {
|
||||
const amount = ethers.utils.parseEther("1") // 1 ETH
|
||||
const flashloanAmount = ethers.utils.parseEther("100") // 100 ETH
|
||||
const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
|
||||
|
||||
const IdOne = "2878734423"
|
||||
const IdTwo = "783243246"
|
||||
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "deposit",
|
||||
args: ["ETH-A", flashloanAmount, 0, IdOne]
|
||||
},
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "withdraw",
|
||||
args: ["ETH-A", amount, IdOne, IdTwo]
|
||||
},
|
||||
{
|
||||
connector: "INSTAPOOL-A",
|
||||
method: "flashPayback",
|
||||
args: [ethAddress, flashloanAmount, IdTwo, 0],
|
||||
}
|
||||
]
|
||||
|
||||
const calldata = encodeFlashcastData(spells);
|
||||
|
||||
const spells2 = [
|
||||
{
|
||||
connector: "INSTAPOOL-A",
|
||||
method: "flashBorrowAndCast",
|
||||
args: [
|
||||
"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
|
||||
flashloanAmount,
|
||||
0, // route
|
||||
calldata,
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells2), wallet1.address)
|
||||
const receipt = await tx.wait()
|
||||
});
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue
Block a user