mirror of
https://github.com/Instadapp/Gelato-automations.git
synced 2024-07-29 22:28:07 +00:00
config: contract dependencies for testing
This commit is contained in:
parent
5e20f89951
commit
40de5ce04c
|
@ -6,7 +6,7 @@ jobs: # a collection of steps
|
|||
- image: circleci/node:12.16.2 # ...with this image as the primary container; this is where all `steps` will run
|
||||
steps: # a collection of executable commands
|
||||
- checkout # special step to check out source code to working directory
|
||||
- restore_cache: # special step to restore the dependency cache
|
||||
- restore_cache: # restore the dependency cache
|
||||
# Read about caching dependencies: https://circleci.com/docs/2.0/caching/
|
||||
name: Restore Yarn Package Cache
|
||||
key: yarn-packages-{{ checksum "yarn.lock" }}
|
||||
|
@ -18,30 +18,37 @@ jobs: # a collection of steps
|
|||
key: yarn-packages-{{ checksum "yarn.lock" }}
|
||||
paths:
|
||||
- ./node_modules
|
||||
- restore_cache: # restore hardhat compile cache
|
||||
name: Restore Hardhat Compilation Cache
|
||||
key: solidity-files-cache-
|
||||
- run: # Compile
|
||||
name: Compile
|
||||
command: yarn compile
|
||||
- save_cache: # special step to save the hardhat compile cache
|
||||
name: Save Hardhat Compilation Cache
|
||||
key: solidity-files-cache-{{ checksum "./cache/solidity-files-cache.json" }}
|
||||
paths:
|
||||
- ./cache/solidity-files-cache.json
|
||||
- run: # Formatting
|
||||
name: Prettier Check
|
||||
command: yarn prettier --check .
|
||||
- run: # Linting
|
||||
name: ESLint
|
||||
command: yarn lint
|
||||
- restore_cache: # special step to restore the Hardhat Network Fork Cache
|
||||
# Read about caching dependencies: https://circleci.com/docs/2.0/caching/
|
||||
- restore_cache: # restore the Hardhat Network Fork Cache
|
||||
name: Restore Hardhat Network Fork Cache
|
||||
key: hardhat-network-fork
|
||||
key: v1-hardhat-network-fork-cache
|
||||
- run: # Tests
|
||||
name: Tests using hardhat mainnet fork and gas reporter
|
||||
command: REPORT_GAS=1 yarn test
|
||||
- save_cache: # special step to save the Hardhat Network Fork cache
|
||||
name: Save Hardhat Network Fork Cache
|
||||
key: v1-hardhat-network-fork-cache
|
||||
paths:
|
||||
- ./cache/hardhat-network-fork
|
||||
- run: # Codechecks
|
||||
name: Codechecks gas reporting
|
||||
command: npx codechecks
|
||||
- save_cache: # special step to save the Hardhat Network Fork cache
|
||||
name: Save Hardhat Network Fork Cache
|
||||
key: hardhat-network-fork
|
||||
paths:
|
||||
- ./cache/hardhat-network-fork
|
||||
# - store_artifacts: # for display in Artifacts: https://circleci.com/docs/2.0/artifacts/
|
||||
# path: coverage
|
||||
# prefix: coverage
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
node_modules/
|
||||
contracts/constants
|
||||
contracts/dependencies
|
||||
contracts/functions
|
||||
contracts/vendor
|
|
@ -4,7 +4,7 @@ pragma solidity 0.7.4;
|
|||
import {
|
||||
GelatoConditionsStandard
|
||||
} from "@gelatonetwork/core/contracts/conditions/GelatoConditionsStandard.sol";
|
||||
import {SafeMath} from "@gelatonetwork/core/contracts/external/SafeMath.sol";
|
||||
import {SafeMath} from "../../../vendor/SafeMath.sol";
|
||||
import {
|
||||
IGelatoCore
|
||||
} from "@gelatonetwork/core/contracts/gelato_core/interfaces/IGelatoCore.sol";
|
||||
|
|
9
contracts/dependencies/GelatoTestDependencies.sol
Normal file
9
contracts/dependencies/GelatoTestDependencies.sol
Normal file
|
@ -0,0 +1,9 @@
|
|||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity 0.6.10;
|
||||
|
||||
import "@gelatonetwork/core/contracts/gelato_core/GelatoCore.sol";
|
||||
|
||||
// solhint-disable-next-line no-empty-blocks
|
||||
contract GelatoTestDependencies {
|
||||
|
||||
}
|
685
contracts/dependencies/InstaDapp/connectors/compound.sol
Normal file
685
contracts/dependencies/InstaDapp/connectors/compound.sol
Normal file
|
@ -0,0 +1,685 @@
|
|||
pragma solidity ^0.6.0;
|
||||
|
||||
interface CTokenInterface {
|
||||
function mint(uint256 mintAmount) external returns (uint256);
|
||||
|
||||
function redeem(uint256 redeemTokens) external returns (uint256);
|
||||
|
||||
function borrow(uint256 borrowAmount) external returns (uint256);
|
||||
|
||||
function repayBorrow(uint256 repayAmount) external returns (uint256);
|
||||
|
||||
function repayBorrowBehalf(address borrower, uint256 repayAmount)
|
||||
external
|
||||
returns (uint256); // For ERC20
|
||||
|
||||
function liquidateBorrow(
|
||||
address borrower,
|
||||
uint256 repayAmount,
|
||||
address cTokenCollateral
|
||||
) external returns (uint256);
|
||||
|
||||
function borrowBalanceCurrent(address account) external returns (uint256);
|
||||
|
||||
function redeemUnderlying(uint256 redeemAmount) external returns (uint256);
|
||||
|
||||
function exchangeRateCurrent() external returns (uint256);
|
||||
|
||||
function balanceOf(address owner) external view returns (uint256 balance);
|
||||
}
|
||||
|
||||
interface CETHInterface {
|
||||
function mint() external payable;
|
||||
|
||||
function repayBorrow() external payable;
|
||||
|
||||
function repayBorrowBehalf(address borrower) external payable;
|
||||
|
||||
function liquidateBorrow(address borrower, address cTokenCollateral)
|
||||
external
|
||||
payable;
|
||||
}
|
||||
|
||||
interface TokenInterface {
|
||||
function allowance(address, address) external view returns (uint256);
|
||||
|
||||
function balanceOf(address) external view returns (uint256);
|
||||
|
||||
function approve(address, uint256) external;
|
||||
|
||||
function transfer(address, uint256) external returns (bool);
|
||||
|
||||
function transferFrom(
|
||||
address,
|
||||
address,
|
||||
uint256
|
||||
) external returns (bool);
|
||||
}
|
||||
|
||||
interface ComptrollerInterface {
|
||||
function enterMarkets(address[] calldata cTokens)
|
||||
external
|
||||
returns (uint256[] memory);
|
||||
|
||||
function exitMarket(address cTokenAddress) external returns (uint256);
|
||||
|
||||
function getAssetsIn(address account)
|
||||
external
|
||||
view
|
||||
returns (address[] memory);
|
||||
|
||||
function getAccountLiquidity(address account)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
uint256,
|
||||
uint256,
|
||||
uint256
|
||||
);
|
||||
|
||||
function claimComp(address) external;
|
||||
}
|
||||
|
||||
interface InstaMapping {
|
||||
function cTokenMapping(address) external view returns (address);
|
||||
}
|
||||
|
||||
interface MemoryInterface {
|
||||
function getUint(uint256 _id) external returns (uint256 _num);
|
||||
|
||||
function setUint(uint256 _id, uint256 _val) external;
|
||||
}
|
||||
|
||||
interface EventInterface {
|
||||
function emitEvent(
|
||||
uint256 _connectorType,
|
||||
uint256 _connectorID,
|
||||
bytes32 _eventCode,
|
||||
bytes calldata _eventData
|
||||
) external;
|
||||
}
|
||||
|
||||
contract DSMath {
|
||||
function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||
require((z = x + y) >= x, "math-not-safe");
|
||||
}
|
||||
|
||||
function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||
require(y == 0 || (z = x * y) / y == x, "math-not-safe");
|
||||
}
|
||||
|
||||
uint256 constant WAD = 10**18;
|
||||
|
||||
function wmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||
z = add(mul(x, y), WAD / 2) / WAD;
|
||||
}
|
||||
|
||||
function wdiv(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||
z = add(mul(x, WAD), y / 2) / y;
|
||||
}
|
||||
|
||||
function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||
require((z = x - y) <= x, "ds-math-sub-underflow");
|
||||
}
|
||||
}
|
||||
|
||||
contract Helpers is DSMath {
|
||||
/**
|
||||
* @dev Return ethereum address
|
||||
*/
|
||||
function getAddressETH() internal pure returns (address) {
|
||||
return 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; // ETH Address
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return Memory Variable Address
|
||||
*/
|
||||
function getMemoryAddr() internal pure returns (address) {
|
||||
return 0x8a5419CfC711B2343c17a6ABf4B2bAFaBb06957F; // InstaMemory Address
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return InstaEvent Address.
|
||||
*/
|
||||
function getEventAddr() internal pure returns (address) {
|
||||
return 0x2af7ea6Cb911035f3eb1ED895Cb6692C39ecbA97; // InstaEvent Address
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Get Uint value from InstaMemory Contract.
|
||||
*/
|
||||
function getUint(uint256 getId, uint256 val)
|
||||
internal
|
||||
returns (uint256 returnVal)
|
||||
{
|
||||
returnVal = getId == 0
|
||||
? val
|
||||
: MemoryInterface(getMemoryAddr()).getUint(getId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Set Uint value in InstaMemory Contract.
|
||||
*/
|
||||
function setUint(uint256 setId, uint256 val) internal {
|
||||
if (setId != 0) MemoryInterface(getMemoryAddr()).setUint(setId, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Connector Details
|
||||
*/
|
||||
function connectorID() public pure returns (uint256 _type, uint256 _id) {
|
||||
(_type, _id) = (1, 24);
|
||||
}
|
||||
}
|
||||
|
||||
contract CompoundHelpers is Helpers {
|
||||
/**
|
||||
* @dev Return Compound Comptroller Address
|
||||
*/
|
||||
function getComptrollerAddress() internal pure returns (address) {
|
||||
return 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return COMP Token Address.
|
||||
*/
|
||||
function getCompTokenAddress() internal pure returns (address) {
|
||||
return 0xc00e94Cb662C3520282E6f5717214004A7f26888;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return InstaDApp Mapping Addresses
|
||||
*/
|
||||
function getMappingAddr() internal pure returns (address) {
|
||||
return 0xe81F70Cc7C0D46e12d70efc60607F16bbD617E88; // InstaMapping Address
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev enter compound market
|
||||
*/
|
||||
function enterMarket(address cToken) internal {
|
||||
ComptrollerInterface troller = ComptrollerInterface(
|
||||
getComptrollerAddress()
|
||||
);
|
||||
address[] memory markets = troller.getAssetsIn(address(this));
|
||||
bool isEntered = false;
|
||||
for (uint256 i = 0; i < markets.length; i++) {
|
||||
if (markets[i] == cToken) {
|
||||
isEntered = true;
|
||||
}
|
||||
}
|
||||
if (!isEntered) {
|
||||
address[] memory toEnter = new address[](1);
|
||||
toEnter[0] = cToken;
|
||||
troller.enterMarkets(toEnter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contract BasicResolver is CompoundHelpers {
|
||||
event LogDeposit(
|
||||
address indexed token,
|
||||
address cToken,
|
||||
uint256 tokenAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
event LogWithdraw(
|
||||
address indexed token,
|
||||
address cToken,
|
||||
uint256 tokenAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
event LogBorrow(
|
||||
address indexed token,
|
||||
address cToken,
|
||||
uint256 tokenAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
event LogPayback(
|
||||
address indexed token,
|
||||
address cToken,
|
||||
uint256 tokenAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev Deposit ETH/ERC20_Token.
|
||||
* @param token token address to deposit.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param amt token amount to deposit.
|
||||
* @param getId Get token amount at this ID from `InstaMemory` Contract.
|
||||
* @param setId Set token amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
function deposit(
|
||||
address token,
|
||||
uint256 amt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) external payable {
|
||||
uint256 _amt = getUint(getId, amt);
|
||||
address cToken = InstaMapping(getMappingAddr()).cTokenMapping(token);
|
||||
enterMarket(cToken);
|
||||
if (token == getAddressETH()) {
|
||||
_amt = _amt == uint256(-1) ? address(this).balance : _amt;
|
||||
CETHInterface(cToken).mint.value(_amt)();
|
||||
} else {
|
||||
TokenInterface tokenContract = TokenInterface(token);
|
||||
_amt = _amt == uint256(-1)
|
||||
? tokenContract.balanceOf(address(this))
|
||||
: _amt;
|
||||
tokenContract.approve(cToken, _amt);
|
||||
require(CTokenInterface(cToken).mint(_amt) == 0, "borrow-failed");
|
||||
}
|
||||
setUint(setId, _amt);
|
||||
|
||||
emit LogDeposit(token, cToken, _amt, getId, setId);
|
||||
bytes32 _eventCode = keccak256(
|
||||
"LogDeposit(address,address,uint256,uint256,uint256)"
|
||||
);
|
||||
bytes memory _eventParam = abi.encode(
|
||||
token,
|
||||
cToken,
|
||||
_amt,
|
||||
getId,
|
||||
setId
|
||||
);
|
||||
(uint256 _type, uint256 _id) = connectorID();
|
||||
EventInterface(getEventAddr()).emitEvent(
|
||||
_type,
|
||||
_id,
|
||||
_eventCode,
|
||||
_eventParam
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Withdraw ETH/ERC20_Token.
|
||||
* @param token token address to withdraw.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param amt token amount to withdraw.
|
||||
* @param getId Get token amount at this ID from `InstaMemory` Contract.
|
||||
* @param setId Set token amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
function withdraw(
|
||||
address token,
|
||||
uint256 amt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) external payable {
|
||||
uint256 _amt = getUint(getId, amt);
|
||||
address cToken = InstaMapping(getMappingAddr()).cTokenMapping(token);
|
||||
CTokenInterface cTokenContract = CTokenInterface(cToken);
|
||||
if (_amt == uint256(-1)) {
|
||||
TokenInterface tokenContract = TokenInterface(token);
|
||||
uint256 initialBal = token == getAddressETH()
|
||||
? address(this).balance
|
||||
: tokenContract.balanceOf(address(this));
|
||||
require(
|
||||
cTokenContract.redeem(
|
||||
cTokenContract.balanceOf(address(this))
|
||||
) == 0,
|
||||
"full-withdraw-failed"
|
||||
);
|
||||
uint256 finalBal = token == getAddressETH()
|
||||
? address(this).balance
|
||||
: tokenContract.balanceOf(address(this));
|
||||
_amt = finalBal - initialBal;
|
||||
} else {
|
||||
require(
|
||||
cTokenContract.redeemUnderlying(_amt) == 0,
|
||||
"withdraw-failed"
|
||||
);
|
||||
}
|
||||
setUint(setId, _amt);
|
||||
|
||||
emit LogWithdraw(token, cToken, _amt, getId, setId);
|
||||
bytes32 _eventCode = keccak256(
|
||||
"LogWithdraw(address,address,uint256,uint256,uint256)"
|
||||
);
|
||||
bytes memory _eventParam = abi.encode(
|
||||
token,
|
||||
cToken,
|
||||
_amt,
|
||||
getId,
|
||||
setId
|
||||
);
|
||||
(uint256 _type, uint256 _id) = connectorID();
|
||||
EventInterface(getEventAddr()).emitEvent(
|
||||
_type,
|
||||
_id,
|
||||
_eventCode,
|
||||
_eventParam
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Borrow ETH/ERC20_Token.
|
||||
* @param token token address to borrow.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param amt token amount to borrow.
|
||||
* @param getId Get token amount at this ID from `InstaMemory` Contract.
|
||||
* @param setId Set token amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
function borrow(
|
||||
address token,
|
||||
uint256 amt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) external payable {
|
||||
uint256 _amt = getUint(getId, amt);
|
||||
address cToken = InstaMapping(getMappingAddr()).cTokenMapping(token);
|
||||
enterMarket(cToken);
|
||||
require(CTokenInterface(cToken).borrow(_amt) == 0, "borrow-failed");
|
||||
setUint(setId, _amt);
|
||||
|
||||
emit LogBorrow(token, cToken, _amt, getId, setId);
|
||||
bytes32 _eventCode = keccak256(
|
||||
"LogBorrow(address,address,uint256,uint256,uint256)"
|
||||
);
|
||||
bytes memory _eventParam = abi.encode(
|
||||
token,
|
||||
cToken,
|
||||
_amt,
|
||||
getId,
|
||||
setId
|
||||
);
|
||||
(uint256 _type, uint256 _id) = connectorID();
|
||||
EventInterface(getEventAddr()).emitEvent(
|
||||
_type,
|
||||
_id,
|
||||
_eventCode,
|
||||
_eventParam
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Payback borrowed ETH/ERC20_Token.
|
||||
* @param token token address to payback.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param amt token amount to payback.
|
||||
* @param getId Get token amount at this ID from `InstaMemory` Contract.
|
||||
* @param setId Set token amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
function payback(
|
||||
address token,
|
||||
uint256 amt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) external payable {
|
||||
uint256 _amt = getUint(getId, amt);
|
||||
address cToken = InstaMapping(getMappingAddr()).cTokenMapping(token);
|
||||
CTokenInterface cTokenContract = CTokenInterface(cToken);
|
||||
_amt = _amt == uint256(-1)
|
||||
? cTokenContract.borrowBalanceCurrent(address(this))
|
||||
: _amt;
|
||||
|
||||
if (token == getAddressETH()) {
|
||||
require(address(this).balance >= _amt, "not-enough-eth");
|
||||
CETHInterface(cToken).repayBorrow.value(_amt)();
|
||||
} else {
|
||||
TokenInterface tokenContract = TokenInterface(token);
|
||||
require(
|
||||
tokenContract.balanceOf(address(this)) >= _amt,
|
||||
"not-enough-token"
|
||||
);
|
||||
tokenContract.approve(cToken, _amt);
|
||||
require(cTokenContract.repayBorrow(_amt) == 0, "repay-failed.");
|
||||
}
|
||||
setUint(setId, _amt);
|
||||
|
||||
emit LogPayback(token, cToken, _amt, getId, setId);
|
||||
bytes32 _eventCode = keccak256(
|
||||
"LogPayback(address,address,uint256,uint256,uint256)"
|
||||
);
|
||||
bytes memory _eventParam = abi.encode(
|
||||
token,
|
||||
cToken,
|
||||
_amt,
|
||||
getId,
|
||||
setId
|
||||
);
|
||||
(uint256 _type, uint256 _id) = connectorID();
|
||||
EventInterface(getEventAddr()).emitEvent(
|
||||
_type,
|
||||
_id,
|
||||
_eventCode,
|
||||
_eventParam
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
contract ExtraResolver is BasicResolver {
|
||||
event LogClaimedComp(uint256 compAmt, uint256 setId);
|
||||
event LogDepositCToken(
|
||||
address indexed token,
|
||||
address cToken,
|
||||
uint256 tokenAmt,
|
||||
uint256 cTokenAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
event LogWithdrawCToken(
|
||||
address indexed token,
|
||||
address cToken,
|
||||
uint256 cTokenAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
event LogLiquidate(
|
||||
address indexed borrower,
|
||||
address indexed tokenToPay,
|
||||
address indexed tokenInReturn,
|
||||
uint256 tokenAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev Claim Accrued COMP Token.
|
||||
* @param setId Set ctoken amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
function ClaimComp(uint256 setId) external payable {
|
||||
TokenInterface compToken = TokenInterface(getCompTokenAddress());
|
||||
uint256 intialBal = compToken.balanceOf(address(this));
|
||||
ComptrollerInterface(getComptrollerAddress()).claimComp(address(this));
|
||||
uint256 finalBal = compToken.balanceOf(address(this));
|
||||
uint256 amt = sub(finalBal, intialBal);
|
||||
|
||||
setUint(setId, amt);
|
||||
|
||||
emit LogClaimedComp(amt, setId);
|
||||
bytes32 _eventCode = keccak256("LogClaimedComp(uint256,uint256)");
|
||||
bytes memory _eventParam = abi.encode(amt, setId);
|
||||
(uint256 _type, uint256 _id) = connectorID();
|
||||
EventInterface(getEventAddr()).emitEvent(
|
||||
_type,
|
||||
_id,
|
||||
_eventCode,
|
||||
_eventParam
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Deposit ETH/ERC20_Token.
|
||||
* @param token token address to depositCToken.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param amt token amount to depositCToken.
|
||||
* @param getId Get token amount at this ID from `InstaMemory` Contract.
|
||||
* @param setId Set ctoken amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
function depositCToken(
|
||||
address token,
|
||||
uint256 amt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) external payable {
|
||||
uint256 _amt = getUint(getId, amt);
|
||||
address cToken = InstaMapping(getMappingAddr()).cTokenMapping(token);
|
||||
enterMarket(cToken);
|
||||
|
||||
CTokenInterface ctokenContract = CTokenInterface(cToken);
|
||||
uint256 initialBal = ctokenContract.balanceOf(address(this));
|
||||
|
||||
if (token == getAddressETH()) {
|
||||
_amt = _amt == uint256(-1) ? address(this).balance : _amt;
|
||||
CETHInterface(cToken).mint.value(_amt)();
|
||||
} else {
|
||||
TokenInterface tokenContract = TokenInterface(token);
|
||||
_amt = _amt == uint256(-1)
|
||||
? tokenContract.balanceOf(address(this))
|
||||
: _amt;
|
||||
tokenContract.approve(cToken, _amt);
|
||||
require(ctokenContract.mint(_amt) == 0, "deposit-ctoken-failed.");
|
||||
}
|
||||
|
||||
uint256 finalBal = ctokenContract.balanceOf(address(this));
|
||||
uint256 _cAmt = finalBal - initialBal;
|
||||
setUint(setId, _cAmt);
|
||||
|
||||
emit LogDepositCToken(token, cToken, _amt, _cAmt, getId, setId);
|
||||
bytes32 _eventCode = keccak256(
|
||||
"LogDepositCToken(address,address,uint256,uint256,uint256,uint256)"
|
||||
);
|
||||
bytes memory _eventParam = abi.encode(
|
||||
token,
|
||||
cToken,
|
||||
_amt,
|
||||
_cAmt,
|
||||
getId,
|
||||
setId
|
||||
);
|
||||
(uint256 _type, uint256 _id) = connectorID();
|
||||
EventInterface(getEventAddr()).emitEvent(
|
||||
_type,
|
||||
_id,
|
||||
_eventCode,
|
||||
_eventParam
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Withdraw CETH/CERC20_Token using cToken Amt.
|
||||
* @param token token address to withdraw CToken.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param cTokenAmt ctoken amount to withdrawCToken.
|
||||
* @param getId Get ctoken amount at this ID from `InstaMemory` Contract.
|
||||
* @param setId Set ctoken amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
function withdrawCToken(
|
||||
address token,
|
||||
uint256 cTokenAmt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) external payable {
|
||||
uint256 _amt = getUint(getId, cTokenAmt);
|
||||
address cToken = InstaMapping(getMappingAddr()).cTokenMapping(token);
|
||||
CTokenInterface cTokenContract = CTokenInterface(cToken);
|
||||
_amt = _amt == uint256(-1)
|
||||
? cTokenContract.balanceOf(address(this))
|
||||
: _amt;
|
||||
require(cTokenContract.redeem(_amt) == 0, "redeem-failed");
|
||||
setUint(setId, _amt);
|
||||
|
||||
emit LogWithdrawCToken(token, cToken, _amt, getId, setId);
|
||||
bytes32 _eventCode = keccak256(
|
||||
"LogWithdrawCToken(address,address,uint256,uint256,uint256)"
|
||||
);
|
||||
bytes memory _eventParam = abi.encode(
|
||||
token,
|
||||
cToken,
|
||||
_amt,
|
||||
getId,
|
||||
setId
|
||||
);
|
||||
(uint256 _type, uint256 _id) = connectorID();
|
||||
EventInterface(getEventAddr()).emitEvent(
|
||||
_type,
|
||||
_id,
|
||||
_eventCode,
|
||||
_eventParam
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Liquidate a position.
|
||||
* @param borrower Borrower's Address.
|
||||
* @param tokenToPay token address to pay for liquidation.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param tokenInReturn token address to return for liquidation.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param amt token amount to pay for liquidation.
|
||||
* @param getId Get token amount at this ID from `InstaMemory` Contract.
|
||||
* @param setId Set token amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
function liquidate(
|
||||
address borrower,
|
||||
address tokenToPay,
|
||||
address tokenInReturn,
|
||||
uint256 amt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) external payable {
|
||||
uint256 _amt = getUint(getId, amt);
|
||||
address cTokenPay = InstaMapping(getMappingAddr()).cTokenMapping(
|
||||
tokenToPay
|
||||
);
|
||||
address cTokenColl = InstaMapping(getMappingAddr()).cTokenMapping(
|
||||
tokenInReturn
|
||||
);
|
||||
CTokenInterface cTokenContract = CTokenInterface(cTokenPay);
|
||||
|
||||
(, , uint256 shortfal) = ComptrollerInterface(getComptrollerAddress())
|
||||
.getAccountLiquidity(borrower);
|
||||
require(shortfal != 0, "account-cannot-be-liquidated");
|
||||
|
||||
_amt = _amt == uint256(-1)
|
||||
? cTokenContract.borrowBalanceCurrent(borrower)
|
||||
: _amt;
|
||||
if (tokenToPay == getAddressETH()) {
|
||||
require(address(this).balance >= _amt, "not-enought-eth");
|
||||
CETHInterface(cTokenPay).liquidateBorrow.value(_amt)(
|
||||
borrower,
|
||||
cTokenColl
|
||||
);
|
||||
} else {
|
||||
TokenInterface tokenContract = TokenInterface(tokenToPay);
|
||||
require(
|
||||
tokenContract.balanceOf(address(this)) >= _amt,
|
||||
"not-enough-token"
|
||||
);
|
||||
tokenContract.approve(cTokenPay, _amt);
|
||||
require(
|
||||
cTokenContract.liquidateBorrow(borrower, _amt, cTokenColl) == 0,
|
||||
"liquidate-failed"
|
||||
);
|
||||
}
|
||||
setUint(setId, _amt);
|
||||
|
||||
emit LogLiquidate(
|
||||
address(this),
|
||||
tokenToPay,
|
||||
tokenInReturn,
|
||||
_amt,
|
||||
getId,
|
||||
setId
|
||||
);
|
||||
bytes32 _eventCode = keccak256(
|
||||
"LogLiquidate(address,address,address,uint256,uint256,uint256)"
|
||||
);
|
||||
bytes memory _eventParam = abi.encode(
|
||||
address(this),
|
||||
tokenToPay,
|
||||
tokenInReturn,
|
||||
_amt,
|
||||
getId,
|
||||
setId
|
||||
);
|
||||
(uint256 _type, uint256 _id) = connectorID();
|
||||
EventInterface(getEventAddr()).emitEvent(
|
||||
_type,
|
||||
_id,
|
||||
_eventCode,
|
||||
_eventParam
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectCompound is ExtraResolver {
|
||||
string public name = "Compound-v1.2";
|
||||
}
|
1121
contracts/dependencies/InstaDapp/connectors/makerdao.sol
Normal file
1121
contracts/dependencies/InstaDapp/connectors/makerdao.sol
Normal file
File diff suppressed because it is too large
Load Diff
177
contracts/dependencies/InstaDapp/dsa-contracts/account.sol
Normal file
177
contracts/dependencies/InstaDapp/dsa-contracts/account.sol
Normal file
|
@ -0,0 +1,177 @@
|
|||
pragma solidity ^0.6.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/**
|
||||
* @title InstaAccount.
|
||||
* @dev DeFi Smart Account Wallet.
|
||||
*/
|
||||
|
||||
interface IndexInterface {
|
||||
function connectors(uint256 version) external view returns (address);
|
||||
|
||||
function check(uint256 version) external view returns (address);
|
||||
|
||||
function list() external view returns (address);
|
||||
}
|
||||
|
||||
interface ConnectorsInterface {
|
||||
function isConnector(address[] calldata logicAddr)
|
||||
external
|
||||
view
|
||||
returns (bool);
|
||||
|
||||
function isStaticConnector(address[] calldata logicAddr)
|
||||
external
|
||||
view
|
||||
returns (bool);
|
||||
}
|
||||
|
||||
interface CheckInterface {
|
||||
function isOk() external view returns (bool);
|
||||
}
|
||||
|
||||
interface ListInterface {
|
||||
function addAuth(address user) external;
|
||||
|
||||
function removeAuth(address user) external;
|
||||
}
|
||||
|
||||
contract Record {
|
||||
event LogEnable(address indexed user);
|
||||
event LogDisable(address indexed user);
|
||||
event LogSwitchShield(bool _shield);
|
||||
|
||||
// InstaIndex Address.
|
||||
address
|
||||
public constant instaIndex = 0x0000000000000000000000000000000000000000;
|
||||
// The Account Module Version.
|
||||
uint256 public constant version = 1;
|
||||
// Auth Module(Address of Auth => bool).
|
||||
mapping(address => bool) private auth;
|
||||
// Is shield true/false.
|
||||
bool public shield;
|
||||
|
||||
/**
|
||||
* @dev Check for Auth if enabled.
|
||||
* @param user address/user/owner.
|
||||
*/
|
||||
function isAuth(address user) public view returns (bool) {
|
||||
return auth[user];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Change Shield State.
|
||||
*/
|
||||
function switchShield(bool _shield) external {
|
||||
require(auth[msg.sender], "not-self");
|
||||
require(shield != _shield, "shield is set");
|
||||
shield = _shield;
|
||||
emit LogSwitchShield(shield);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Enable New User.
|
||||
* @param user Owner of the Smart Account.
|
||||
*/
|
||||
function enable(address user) public {
|
||||
require(
|
||||
msg.sender == address(this) || msg.sender == instaIndex,
|
||||
"not-self-index"
|
||||
);
|
||||
require(user != address(0), "not-valid");
|
||||
require(!auth[user], "already-enabled");
|
||||
auth[user] = true;
|
||||
ListInterface(IndexInterface(instaIndex).list()).addAuth(user);
|
||||
emit LogEnable(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Disable User.
|
||||
* @param user Owner of the Smart Account.
|
||||
*/
|
||||
function disable(address user) public {
|
||||
require(msg.sender == address(this), "not-self");
|
||||
require(user != address(0), "not-valid");
|
||||
require(auth[user], "already-disabled");
|
||||
delete auth[user];
|
||||
ListInterface(IndexInterface(instaIndex).list()).removeAuth(user);
|
||||
emit LogDisable(user);
|
||||
}
|
||||
}
|
||||
|
||||
contract InstaAccount is Record {
|
||||
event LogCast(
|
||||
address indexed origin,
|
||||
address indexed sender,
|
||||
uint256 value
|
||||
);
|
||||
|
||||
receive() external payable {}
|
||||
|
||||
/**
|
||||
* @dev Delegate the calls to Connector And this function is ran by cast().
|
||||
* @param _target Target to of Connector.
|
||||
* @param _data CallData of function in Connector.
|
||||
*/
|
||||
function spell(address _target, bytes memory _data) internal {
|
||||
require(_target != address(0), "target-invalid");
|
||||
assembly {
|
||||
let succeeded := delegatecall(
|
||||
gas(),
|
||||
_target,
|
||||
add(_data, 0x20),
|
||||
mload(_data),
|
||||
0,
|
||||
0
|
||||
)
|
||||
|
||||
switch iszero(succeeded)
|
||||
case 1 {
|
||||
// throw if delegatecall failed
|
||||
let size := returndatasize()
|
||||
returndatacopy(0x00, 0x00, size)
|
||||
revert(0x00, size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev This is the main function, Where all the different functions are called
|
||||
* from Smart Account.
|
||||
* @param _targets Array of Target(s) to of Connector.
|
||||
* @param _datas Array of Calldata(S) of function.
|
||||
*/
|
||||
function cast(
|
||||
address[] calldata _targets,
|
||||
bytes[] calldata _datas,
|
||||
address _origin
|
||||
) external payable {
|
||||
require(
|
||||
isAuth(msg.sender) || msg.sender == instaIndex,
|
||||
"permission-denied"
|
||||
);
|
||||
require(_targets.length == _datas.length, "array-length-invalid");
|
||||
IndexInterface indexContract = IndexInterface(instaIndex);
|
||||
bool isShield = shield;
|
||||
if (!isShield) {
|
||||
require(
|
||||
ConnectorsInterface(indexContract.connectors(version))
|
||||
.isConnector(_targets),
|
||||
"not-connector"
|
||||
);
|
||||
} else {
|
||||
require(
|
||||
ConnectorsInterface(indexContract.connectors(version))
|
||||
.isStaticConnector(_targets),
|
||||
"not-static-connector"
|
||||
);
|
||||
}
|
||||
for (uint256 i = 0; i < _targets.length; i++) {
|
||||
spell(_targets[i], _datas[i]);
|
||||
}
|
||||
address _check = indexContract.check(version);
|
||||
if (_check != address(0) && !isShield)
|
||||
require(CheckInterface(_check).isOk(), "not-ok");
|
||||
emit LogCast(_origin, msg.sender, msg.value);
|
||||
}
|
||||
}
|
200
contracts/dependencies/InstaDapp/dsa-contracts/connectors.sol
Normal file
200
contracts/dependencies/InstaDapp/dsa-contracts/connectors.sol
Normal file
|
@ -0,0 +1,200 @@
|
|||
pragma solidity ^0.6.0;
|
||||
|
||||
/**
|
||||
* @title InstaConnectors
|
||||
* @dev Registry for Connectors.
|
||||
*/
|
||||
|
||||
interface IndexInterface {
|
||||
function master() external view returns (address);
|
||||
}
|
||||
|
||||
interface ConnectorInterface {
|
||||
function connectorID() external view returns (uint256 _type, uint256 _id);
|
||||
|
||||
function name() external view returns (string memory);
|
||||
}
|
||||
|
||||
contract DSMath {
|
||||
function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||
require((z = x + y) >= x, "ds-math-add-overflow");
|
||||
}
|
||||
|
||||
function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||
require((z = x - y) <= x, "ds-math-sub-underflow");
|
||||
}
|
||||
}
|
||||
|
||||
contract Controllers is DSMath {
|
||||
event LogAddController(address indexed addr);
|
||||
event LogRemoveController(address indexed addr);
|
||||
|
||||
// InstaIndex Address.
|
||||
address
|
||||
public constant instaIndex = 0x0000000000000000000000000000000000000000;
|
||||
|
||||
// Enabled Chief(Address of Chief => bool).
|
||||
mapping(address => bool) public chief;
|
||||
// Enabled Connectors(Connector Address => bool).
|
||||
mapping(address => bool) public connectors;
|
||||
// Enabled Static Connectors(Connector Address => bool).
|
||||
mapping(address => bool) public staticConnectors;
|
||||
|
||||
/**
|
||||
* @dev Throws if the sender not is Master Address from InstaIndex
|
||||
* or Enabled Chief.
|
||||
*/
|
||||
modifier isChief {
|
||||
require(
|
||||
chief[msg.sender] ||
|
||||
msg.sender == IndexInterface(instaIndex).master(),
|
||||
"not-an-chief"
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Enable a Chief.
|
||||
* @param _userAddress Chief Address.
|
||||
*/
|
||||
function enableChief(address _userAddress) external isChief {
|
||||
chief[_userAddress] = true;
|
||||
emit LogAddController(_userAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Disables a Chief.
|
||||
* @param _userAddress Chief Address.
|
||||
*/
|
||||
function disableChief(address _userAddress) external isChief {
|
||||
delete chief[_userAddress];
|
||||
emit LogRemoveController(_userAddress);
|
||||
}
|
||||
}
|
||||
|
||||
contract Listings is Controllers {
|
||||
// Connectors Array.
|
||||
address[] public connectorArray;
|
||||
// Count of Connector's Enabled.
|
||||
uint256 public connectorCount;
|
||||
|
||||
/**
|
||||
* @dev Add Connector to Connector's array.
|
||||
* @param _connector Connector Address.
|
||||
**/
|
||||
function addToArr(address _connector) internal {
|
||||
require(_connector != address(0), "Not-valid-connector");
|
||||
(, uint256 _id) = ConnectorInterface(_connector).connectorID();
|
||||
require(_id == (connectorArray.length + 1), "ConnectorID-doesnt-match");
|
||||
ConnectorInterface(_connector).name(); // Checking if connector has function name()
|
||||
connectorArray.push(_connector);
|
||||
}
|
||||
|
||||
// Static Connectors Array.
|
||||
address[] public staticConnectorArray;
|
||||
|
||||
/**
|
||||
* @dev Add Connector to Static Connector's array.
|
||||
* @param _connector Static Connector Address.
|
||||
**/
|
||||
function addToArrStatic(address _connector) internal {
|
||||
require(_connector != address(0), "Not-valid-connector");
|
||||
(, uint256 _id) = ConnectorInterface(_connector).connectorID();
|
||||
require(
|
||||
_id == (staticConnectorArray.length + 1),
|
||||
"ConnectorID-doesnt-match"
|
||||
);
|
||||
ConnectorInterface(_connector).name(); // Checking if connector has function name()
|
||||
staticConnectorArray.push(_connector);
|
||||
}
|
||||
}
|
||||
|
||||
contract InstaConnectors is Listings {
|
||||
event LogEnable(address indexed connector);
|
||||
event LogDisable(address indexed connector);
|
||||
event LogEnableStatic(address indexed connector);
|
||||
|
||||
/**
|
||||
* @dev Enable Connector.
|
||||
* @param _connector Connector Address.
|
||||
*/
|
||||
function enable(address _connector) external isChief {
|
||||
require(!connectors[_connector], "already-enabled");
|
||||
addToArr(_connector);
|
||||
connectors[_connector] = true;
|
||||
connectorCount++;
|
||||
emit LogEnable(_connector);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Disable Connector.
|
||||
* @param _connector Connector Address.
|
||||
*/
|
||||
function disable(address _connector) external isChief {
|
||||
require(connectors[_connector], "already-disabled");
|
||||
delete connectors[_connector];
|
||||
connectorCount--;
|
||||
emit LogDisable(_connector);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Enable Static Connector.
|
||||
* @param _connector Static Connector Address.
|
||||
*/
|
||||
function enableStatic(address _connector) external isChief {
|
||||
require(!staticConnectors[_connector], "already-enabled");
|
||||
addToArrStatic(_connector);
|
||||
staticConnectors[_connector] = true;
|
||||
emit LogEnableStatic(_connector);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Check if Connector addresses are enabled.
|
||||
* @param _connectors Array of Connector Addresses.
|
||||
*/
|
||||
function isConnector(address[] calldata _connectors)
|
||||
external
|
||||
view
|
||||
returns (bool isOk)
|
||||
{
|
||||
isOk = true;
|
||||
for (uint256 i = 0; i < _connectors.length; i++) {
|
||||
if (!connectors[_connectors[i]]) {
|
||||
isOk = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Check if Connector addresses are static enabled.
|
||||
* @param _connectors Array of Connector Addresses.
|
||||
*/
|
||||
function isStaticConnector(address[] calldata _connectors)
|
||||
external
|
||||
view
|
||||
returns (bool isOk)
|
||||
{
|
||||
isOk = true;
|
||||
for (uint256 i = 0; i < _connectors.length; i++) {
|
||||
if (!staticConnectors[_connectors[i]]) {
|
||||
isOk = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev get Connector's Array length.
|
||||
*/
|
||||
function connectorLength() external view returns (uint256) {
|
||||
return connectorArray.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev get Static Connector's Array length.
|
||||
*/
|
||||
function staticConnectorLength() external view returns (uint256) {
|
||||
return staticConnectorArray.length;
|
||||
}
|
||||
}
|
255
contracts/dependencies/InstaDapp/dsa-contracts/index.sol
Normal file
255
contracts/dependencies/InstaDapp/dsa-contracts/index.sol
Normal file
|
@ -0,0 +1,255 @@
|
|||
pragma solidity ^0.6.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/**
|
||||
* @title InstaIndex
|
||||
* @dev Main Contract For DeFi Smart Accounts. This is also a factory contract, Which deploys new Smart Account.
|
||||
* Also Registry for DeFi Smart Accounts.
|
||||
*/
|
||||
|
||||
interface AccountInterface {
|
||||
function version() external view returns (uint256);
|
||||
|
||||
function enable(address authority) external;
|
||||
|
||||
function cast(
|
||||
address[] calldata _targets,
|
||||
bytes[] calldata _datas,
|
||||
address _origin
|
||||
) external payable returns (bytes32[] memory responses);
|
||||
}
|
||||
|
||||
interface ListInterface {
|
||||
function init(address _account) external;
|
||||
}
|
||||
|
||||
contract AddressIndex {
|
||||
event LogNewMaster(address indexed master);
|
||||
event LogUpdateMaster(address indexed master);
|
||||
event LogNewCheck(uint256 indexed accountVersion, address indexed check);
|
||||
event LogNewAccount(
|
||||
address indexed _newAccount,
|
||||
address indexed _connectors,
|
||||
address indexed _check
|
||||
);
|
||||
|
||||
// New Master Address.
|
||||
address private newMaster;
|
||||
// Master Address.
|
||||
address public master;
|
||||
// List Registry Address.
|
||||
address public list;
|
||||
|
||||
// Connectors Modules(Account Module Version => Connectors Registry Module Address).
|
||||
mapping(uint256 => address) public connectors;
|
||||
// Check Modules(Account Module Version => Check Module Address).
|
||||
mapping(uint256 => address) public check;
|
||||
// Account Modules(Account Module Version => Account Module Address).
|
||||
mapping(uint256 => address) public account;
|
||||
// Version Count of Account Modules.
|
||||
uint256 public versionCount;
|
||||
|
||||
/**
|
||||
* @dev Throws if the sender not is Master Address.
|
||||
*/
|
||||
modifier isMaster() {
|
||||
require(msg.sender == master, "not-master");
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Change the Master Address.
|
||||
* @param _newMaster New Master Address.
|
||||
*/
|
||||
function changeMaster(address _newMaster) external isMaster {
|
||||
require(_newMaster != master, "already-a-master");
|
||||
require(_newMaster != address(0), "not-valid-address");
|
||||
require(newMaster != _newMaster, "already-a-new-master");
|
||||
newMaster = _newMaster;
|
||||
emit LogNewMaster(_newMaster);
|
||||
}
|
||||
|
||||
function updateMaster() external {
|
||||
require(newMaster != address(0), "not-valid-address");
|
||||
require(msg.sender == newMaster, "not-master");
|
||||
master = newMaster;
|
||||
newMaster = address(0);
|
||||
emit LogUpdateMaster(master);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Change the Check Address of a specific Account Module version.
|
||||
* @param accountVersion Account Module version.
|
||||
* @param _newCheck The New Check Address.
|
||||
*/
|
||||
function changeCheck(uint256 accountVersion, address _newCheck)
|
||||
external
|
||||
isMaster
|
||||
{
|
||||
require(_newCheck != check[accountVersion], "already-a-check");
|
||||
check[accountVersion] = _newCheck;
|
||||
emit LogNewCheck(accountVersion, _newCheck);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Add New Account Module.
|
||||
* @param _newAccount The New Account Module Address.
|
||||
* @param _connectors Connectors Registry Module Address.
|
||||
* @param _check Check Module Address.
|
||||
*/
|
||||
function addNewAccount(
|
||||
address _newAccount,
|
||||
address _connectors,
|
||||
address _check
|
||||
) external isMaster {
|
||||
require(_newAccount != address(0), "not-valid-address");
|
||||
versionCount++;
|
||||
require(
|
||||
AccountInterface(_newAccount).version() == versionCount,
|
||||
"not-valid-version"
|
||||
);
|
||||
account[versionCount] = _newAccount;
|
||||
if (_connectors != address(0)) connectors[versionCount] = _connectors;
|
||||
if (_check != address(0)) check[versionCount] = _check;
|
||||
emit LogNewAccount(_newAccount, _connectors, _check);
|
||||
}
|
||||
}
|
||||
|
||||
contract CloneFactory is AddressIndex {
|
||||
/**
|
||||
* @dev Clone a new Account Module.
|
||||
* @param version Account Module version to clone.
|
||||
*/
|
||||
function createClone(uint256 version) internal returns (address result) {
|
||||
bytes20 targetBytes = bytes20(account[version]);
|
||||
// solium-disable-next-line security/no-inline-assembly
|
||||
assembly {
|
||||
let clone := mload(0x40)
|
||||
mstore(
|
||||
clone,
|
||||
0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000
|
||||
)
|
||||
mstore(add(clone, 0x14), targetBytes)
|
||||
mstore(
|
||||
add(clone, 0x28),
|
||||
0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000
|
||||
)
|
||||
result := create(0, clone, 0x37)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Check if Account Module is a clone.
|
||||
* @param version Account Module version.
|
||||
* @param query Account Module Address.
|
||||
*/
|
||||
function isClone(uint256 version, address query)
|
||||
external
|
||||
view
|
||||
returns (bool result)
|
||||
{
|
||||
bytes20 targetBytes = bytes20(account[version]);
|
||||
// solium-disable-next-line security/no-inline-assembly
|
||||
assembly {
|
||||
let clone := mload(0x40)
|
||||
mstore(
|
||||
clone,
|
||||
0x363d3d373d3d3d363d7300000000000000000000000000000000000000000000
|
||||
)
|
||||
mstore(add(clone, 0xa), targetBytes)
|
||||
mstore(
|
||||
add(clone, 0x1e),
|
||||
0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000
|
||||
)
|
||||
|
||||
let other := add(clone, 0x40)
|
||||
extcodecopy(query, other, 0, 0x2d)
|
||||
result := and(
|
||||
eq(mload(clone), mload(other)),
|
||||
eq(mload(add(clone, 0xd)), mload(add(other, 0xd)))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contract InstaIndex is CloneFactory {
|
||||
event LogAccountCreated(
|
||||
address sender,
|
||||
address indexed owner,
|
||||
address indexed account,
|
||||
address indexed origin
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev Create a new DeFi Smart Account for a user and run cast function in the new Smart Account.
|
||||
* @param _owner Owner of the Smart Account.
|
||||
* @param accountVersion Account Module version.
|
||||
* @param _targets Array of Target to run cast function.
|
||||
* @param _datas Array of Data(callData) to run cast function.
|
||||
* @param _origin Where Smart Account is created.
|
||||
*/
|
||||
function buildWithCast(
|
||||
address _owner,
|
||||
uint256 accountVersion,
|
||||
address[] calldata _targets,
|
||||
bytes[] calldata _datas,
|
||||
address _origin
|
||||
) external payable returns (address _account) {
|
||||
_account = build(_owner, accountVersion, _origin);
|
||||
if (_targets.length > 0)
|
||||
AccountInterface(_account).cast.value(msg.value)(
|
||||
_targets,
|
||||
_datas,
|
||||
_origin
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Create a new DeFi Smart Account for a user.
|
||||
* @param _owner Owner of the Smart Account.
|
||||
* @param accountVersion Account Module version.
|
||||
* @param _origin Where Smart Account is created.
|
||||
*/
|
||||
function build(
|
||||
address _owner,
|
||||
uint256 accountVersion,
|
||||
address _origin
|
||||
) public returns (address _account) {
|
||||
require(
|
||||
accountVersion != 0 && accountVersion <= versionCount,
|
||||
"not-valid-account"
|
||||
);
|
||||
_account = createClone(accountVersion);
|
||||
ListInterface(list).init(_account);
|
||||
AccountInterface(_account).enable(_owner);
|
||||
emit LogAccountCreated(msg.sender, _owner, _account, _origin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Setup Initial things for InstaIndex, after its been deployed and can be only run once.
|
||||
* @param _master The Master Address.
|
||||
* @param _list The List Address.
|
||||
* @param _account The Account Module Address.
|
||||
* @param _connectors The Connectors Registry Module Address.
|
||||
*/
|
||||
function setBasics(
|
||||
address _master,
|
||||
address _list,
|
||||
address _account,
|
||||
address _connectors
|
||||
) external {
|
||||
require(
|
||||
master == address(0) &&
|
||||
list == address(0) &&
|
||||
account[1] == address(0) &&
|
||||
connectors[1] == address(0) &&
|
||||
versionCount == 0,
|
||||
"already-defined"
|
||||
);
|
||||
master = _master;
|
||||
list = _list;
|
||||
versionCount++;
|
||||
account[versionCount] = _account;
|
||||
connectors[versionCount] = _connectors;
|
||||
}
|
||||
}
|
163
contracts/dependencies/InstaDapp/dsa-contracts/list.sol
Normal file
163
contracts/dependencies/InstaDapp/dsa-contracts/list.sol
Normal file
|
@ -0,0 +1,163 @@
|
|||
pragma solidity ^0.6.0;
|
||||
|
||||
/**
|
||||
* @title InstaList
|
||||
* @dev Registry For DeFi Smart Account Authorised user.
|
||||
*/
|
||||
|
||||
interface AccountInterface {
|
||||
function isAuth(address _user) external view returns (bool);
|
||||
}
|
||||
|
||||
contract DSMath {
|
||||
function add(uint64 x, uint64 y) internal pure returns (uint64 z) {
|
||||
require((z = x + y) >= x, "ds-math-add-overflow");
|
||||
}
|
||||
|
||||
function sub(uint64 x, uint64 y) internal pure returns (uint64 z) {
|
||||
require((z = x - y) <= x, "ds-math-sub-underflow");
|
||||
}
|
||||
}
|
||||
|
||||
contract Variables is DSMath {
|
||||
// InstaIndex Address.
|
||||
address
|
||||
public constant instaIndex = 0x0000000000000000000000000000000000000000;
|
||||
|
||||
// Smart Account Count.
|
||||
uint64 public accounts;
|
||||
// Smart Account ID (Smart Account Address => Account ID).
|
||||
mapping(address => uint64) public accountID;
|
||||
// Smart Account Address (Smart Account ID => Smart Account Address).
|
||||
mapping(uint64 => address) public accountAddr;
|
||||
|
||||
// User Link (User Address => UserLink(Account ID of First and Last And Count of Smart Accounts)).
|
||||
mapping(address => UserLink) public userLink;
|
||||
// Linked List of Users (User Address => Smart Account ID => UserList(Previous and next Account ID)).
|
||||
mapping(address => mapping(uint64 => UserList)) public userList;
|
||||
|
||||
struct UserLink {
|
||||
uint64 first;
|
||||
uint64 last;
|
||||
uint64 count;
|
||||
}
|
||||
struct UserList {
|
||||
uint64 prev;
|
||||
uint64 next;
|
||||
}
|
||||
|
||||
// Account Link (Smart Account ID => AccountLink).
|
||||
mapping(uint64 => AccountLink) public accountLink; // account => account linked list connection
|
||||
// Linked List of Accounts (Smart Account ID => Account Address => AccountList).
|
||||
mapping(uint64 => mapping(address => AccountList)) public accountList; // account => user address => list
|
||||
|
||||
struct AccountLink {
|
||||
address first;
|
||||
address last;
|
||||
uint64 count;
|
||||
}
|
||||
struct AccountList {
|
||||
address prev;
|
||||
address next;
|
||||
}
|
||||
}
|
||||
|
||||
contract Configure is Variables {
|
||||
/**
|
||||
* @dev Add Account to User Linked List.
|
||||
* @param _owner Account Owner.
|
||||
* @param _account Smart Account Address.
|
||||
*/
|
||||
function addAccount(address _owner, uint64 _account) internal {
|
||||
if (userLink[_owner].last != 0) {
|
||||
userList[_owner][_account].prev = userLink[_owner].last;
|
||||
userList[_owner][userLink[_owner].last].next = _account;
|
||||
}
|
||||
if (userLink[_owner].first == 0) userLink[_owner].first = _account;
|
||||
userLink[_owner].last = _account;
|
||||
userLink[_owner].count = add(userLink[_owner].count, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Remove Account from User Linked List.
|
||||
* @param _owner Account Owner/User.
|
||||
* @param _account Smart Account Address.
|
||||
*/
|
||||
function removeAccount(address _owner, uint64 _account) internal {
|
||||
uint64 _prev = userList[_owner][_account].prev;
|
||||
uint64 _next = userList[_owner][_account].next;
|
||||
if (_prev != 0) userList[_owner][_prev].next = _next;
|
||||
if (_next != 0) userList[_owner][_next].prev = _prev;
|
||||
if (_prev == 0) userLink[_owner].first = _next;
|
||||
if (_next == 0) userLink[_owner].last = _prev;
|
||||
userLink[_owner].count = sub(userLink[_owner].count, 1);
|
||||
delete userList[_owner][_account];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Add Owner to Account Linked List.
|
||||
* @param _owner Account Owner.
|
||||
* @param _account Smart Account Address.
|
||||
*/
|
||||
function addUser(address _owner, uint64 _account) internal {
|
||||
if (accountLink[_account].last != address(0)) {
|
||||
accountList[_account][_owner].prev = accountLink[_account].last;
|
||||
accountList[_account][accountLink[_account].last].next = _owner;
|
||||
}
|
||||
if (accountLink[_account].first == address(0))
|
||||
accountLink[_account].first = _owner;
|
||||
accountLink[_account].last = _owner;
|
||||
accountLink[_account].count = add(accountLink[_account].count, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Remove Owner from Account Linked List.
|
||||
* @param _owner Account Owner.
|
||||
* @param _account Smart Account Address.
|
||||
*/
|
||||
function removeUser(address _owner, uint64 _account) internal {
|
||||
address _prev = accountList[_account][_owner].prev;
|
||||
address _next = accountList[_account][_owner].next;
|
||||
if (_prev != address(0)) accountList[_account][_prev].next = _next;
|
||||
if (_next != address(0)) accountList[_account][_next].prev = _prev;
|
||||
if (_prev == address(0)) accountLink[_account].first = _next;
|
||||
if (_next == address(0)) accountLink[_account].last = _prev;
|
||||
accountLink[_account].count = sub(accountLink[_account].count, 1);
|
||||
delete accountList[_account][_owner];
|
||||
}
|
||||
}
|
||||
|
||||
contract InstaList is Configure {
|
||||
/**
|
||||
* @dev Enable Auth for Smart Account.
|
||||
* @param _owner Owner Address.
|
||||
*/
|
||||
function addAuth(address _owner) external {
|
||||
require(accountID[msg.sender] != 0, "not-account");
|
||||
require(AccountInterface(msg.sender).isAuth(_owner), "not-owner");
|
||||
addAccount(_owner, accountID[msg.sender]);
|
||||
addUser(_owner, accountID[msg.sender]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Disable Auth for Smart Account.
|
||||
* @param _owner Owner Address.
|
||||
*/
|
||||
function removeAuth(address _owner) external {
|
||||
require(accountID[msg.sender] != 0, "not-account");
|
||||
require(!AccountInterface(msg.sender).isAuth(_owner), "already-owner");
|
||||
removeAccount(_owner, accountID[msg.sender]);
|
||||
removeUser(_owner, accountID[msg.sender]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Setup Initial configuration of Smart Account.
|
||||
* @param _account Smart Account Address.
|
||||
*/
|
||||
function init(address _account) external {
|
||||
require(msg.sender == instaIndex, "not-index");
|
||||
accounts++;
|
||||
accountID[_account] = accounts;
|
||||
accountAddr[accounts] = _account;
|
||||
}
|
||||
}
|
|
@ -91,10 +91,40 @@ module.exports = {
|
|||
},
|
||||
},
|
||||
solidity: {
|
||||
version: "0.7.4",
|
||||
settings: {
|
||||
optimizer: {enabled: process.env.DEBUG ? false : true},
|
||||
},
|
||||
compilers: [
|
||||
{
|
||||
version: "0.6.10",
|
||||
settings: {
|
||||
optimizer: {enabled: process.env.DEBUG ? false : true},
|
||||
},
|
||||
},
|
||||
{
|
||||
version: "0.7.4",
|
||||
settings: {
|
||||
optimizer: {enabled: process.env.DEBUG ? false : true},
|
||||
},
|
||||
},
|
||||
],
|
||||
// overrides: {
|
||||
// "contracts/vendor/DependenciesSix.sol": {
|
||||
// version: "0.6.10",
|
||||
// settings: {
|
||||
// optimizer: {enabled: process.env.DEBUG ? false : true},
|
||||
// },
|
||||
// },
|
||||
// "@gelatonetwork/core/contracts/gelato_core/GelatoCore.sol": {
|
||||
// version: "0.6.10",
|
||||
// settings: {
|
||||
// optimizer: {enabled: process.env.DEBUG ? false : true},
|
||||
// },
|
||||
// },
|
||||
// "@gelatonetwork/core/contracts/external/Ownable.sol": {
|
||||
// version: "0.6.10",
|
||||
// settings: {
|
||||
// optimizer: {enabled: process.env.DEBUG ? false : true},
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
"debug": "DEBUG=true yarn compile && npx hardhat test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@codechecks/client": "^0.1.10",
|
||||
"@gelatonetwork/core": "1.0.0",
|
||||
"@codechecks/client": "0.1.10",
|
||||
"@gelatonetwork/core": "1.3.1",
|
||||
"@nomiclabs/hardhat-ethers": "2.0.0",
|
||||
"@nomiclabs/hardhat-waffle": "2.0.0",
|
||||
"chai": "4.2.0",
|
||||
|
@ -28,8 +28,8 @@
|
|||
"ethers": "5.0.19",
|
||||
"hardhat": "2.0.2",
|
||||
"hardhat-deploy": "0.7.0-beta.28",
|
||||
"hardhat-deploy-ethers": "^0.3.0-beta.5",
|
||||
"hardhat-gas-reporter": "^1.0.1",
|
||||
"hardhat-deploy-ethers": "0.3.0-beta.5",
|
||||
"hardhat-gas-reporter": "1.0.1",
|
||||
"husky": ">=4",
|
||||
"lint-staged": "10.5.1",
|
||||
"prettier": "2.1.2",
|
||||
|
|
14
yarn.lock
14
yarn.lock
|
@ -23,7 +23,7 @@
|
|||
chalk "^2.0.0"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@codechecks/client@^0.1.10":
|
||||
"@codechecks/client@0.1.10":
|
||||
version "0.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@codechecks/client/-/client-0.1.10.tgz#41fe736c424976d9feb8116b131fb9c1f099d105"
|
||||
integrity sha512-rvX+LknmMohsLTU8mHJqIcNTo8fKfw6A5i7JvT6JJWqwCLi+TujHpRO8BLf48iF96+gU5viVvKfRaUyhc3wloA==
|
||||
|
@ -550,10 +550,10 @@
|
|||
"@ethersproject/properties" "^5.0.3"
|
||||
"@ethersproject/strings" "^5.0.4"
|
||||
|
||||
"@gelatonetwork/core@1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@gelatonetwork/core/-/core-1.0.0.tgz#57caedca0a19c945f509fc714358ab695aec7909"
|
||||
integrity sha512-VuN+bVD8w+X/zwfFDOZHivuNOnzIHhHU0nYj8KJ01toFRnX6ABX428xUOO73mRQsiPVhmRxTu3eBBn9roWaNJw==
|
||||
"@gelatonetwork/core@1.3.1":
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@gelatonetwork/core/-/core-1.3.1.tgz#cff0cb4d06a2bbb7859f3918995f44efc692bb11"
|
||||
integrity sha512-xnl9jskZfAwwaJlIxmiXI+Cm1eKnPoDDBbMPlkNJ2NCDxoDOq/6tjHm9VXIVPDTjpqmNSPzQJjDxFWDrKUrosQ==
|
||||
|
||||
"@nomiclabs/ethereumjs-vm@^4.1.1":
|
||||
version "4.2.0"
|
||||
|
@ -4448,7 +4448,7 @@ har-validator@~5.1.3:
|
|||
ajv "^6.12.3"
|
||||
har-schema "^2.0.0"
|
||||
|
||||
hardhat-deploy-ethers@^0.3.0-beta.5:
|
||||
hardhat-deploy-ethers@0.3.0-beta.5:
|
||||
version "0.3.0-beta.5"
|
||||
resolved "https://registry.yarnpkg.com/hardhat-deploy-ethers/-/hardhat-deploy-ethers-0.3.0-beta.5.tgz#c365ebb5c29e7474b2b35912f27dc9699a0e63b3"
|
||||
integrity sha512-KoUswkCPSuARGjZQIf8kItL5rPFt6srgVj+q0B9YTQ7Vyw/k2N0R8u7aYWq4Piy9mjDKcEGQTPBXhaX02BMkVw==
|
||||
|
@ -4478,7 +4478,7 @@ hardhat-deploy@0.7.0-beta.28:
|
|||
murmur-128 "^0.2.1"
|
||||
qs "^6.9.4"
|
||||
|
||||
hardhat-gas-reporter@^1.0.1:
|
||||
hardhat-gas-reporter@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.1.tgz#37f96da5f11e5ae34b28a68c5d972d3168165c95"
|
||||
integrity sha512-YC+SCYIkBdRtISNbisU2BwDSelUdCrIKRsJXt3M9Jw1VF5CmtSZb8VuuOc2Zl4AMcEV2jEy6ZuAksYomPiApYQ==
|
||||
|
|
Loading…
Reference in New Issue
Block a user