This is a project with Zerion Smart Contracts interacting with different DeFi protocols.
- AdapterRegistry
- AdapterAssetsManager
- Ownable
- adapters/AaveAdapter
- adapters/CompoundAdapter
- adapters/CurveAdapter
- adapters/DSRAdapter
- adapters/MCDAdapter
- adapters/MKRAdapter (abstract contract)
- adapters/PoolTogetherAdapter
- adapters/SynthetixAdapter
- adapters/ZrxAdapter
- adapters/Adapter (abstract contract)
- Logic
- TokenSpender
- interactiveAdapters/InteractiveAdapter (abstract contract)
- Use-cases for Logic contract
- Dev notes
AdapterRegistry is AdapterAssetsManager
Registry holding array of protocol adapters and checking balances via these adapters.
Iterates over adapters
list and appends balances and rates.
Iterates over adapters
list and appends balances.
Iterates over adapters
list and appends rates.
Iterates over adapter
's assets and appends balances.
Iterates over adapter
's assets and appends rates.
function getBalances(address user, address adapter, address[] memory assets) returns (AssetBalance[] memory)
Iterates over given assets
for given adapter
and appends balances.
Iterates over given assets
for given adapter
and appends rates.
s
AdapterAssetsManager is Ownable
Base contract for AdapterRegistry
contract.
Implements logic connected with Adapter
s and their assets
management.
mapping(address => address) internal adapters;
mapping(address => address[]) internal assets;
New adapter is added before the first existing adapter.
New asset is added after the last adapter's asset.
Base contract for AdapterAssetsManager
and Logic
contracts.
Implements Ownable
logic.
Includes onlyOwner
modifier, transferOwnership()
function, and public state variable owner
.
AaveAdapter is Adapter
Adapter for Aave protocol.
CompoundAdapter is Adapter
Adapter for Compound protocol.
CurveAdapter is Adapter
Adapter for curve.fi protocol. Currently, there is the only pool with cDAI/cUSDC locked on it.
DSRAdapter is Adapter
Adapter for DSR protocol.
MCDAdapter is Adapter
Adapter for MCD vaults.
Base contract for Maker adapters.
It includes all the required constants and pure
functions with calculations.
PoolTogetherAdapter is Adapter
Adapter for PoolTogether protocol.
SynthetixAdapter is Adapter
Adapter for Synthetix protocol.
getAssetAmount()
function returns the following amounts:
- amount of SNX tokens locked by minting sUSD tokens (positive);
- amount of sUSD that should be burned to unlock SNX tokens (negative).
ZrxAdapter is Adapter
Adapter for Zrx protocol.
Base contract for protocol adapters.
Includes all the functions required to be implemented.
Should be stateless.
Only internal constant
state variables may be used.
MUST return name of the protocol.
MUST return amount of the given asset locked on the protocol by the given user.
MUST return struct with underlying assets exchange rates for the given asset.
Exchange rate is a number, such that
underlying asset amount = asset amount * exchange rate / 1e18
Note: rates are scaled by 1e18
due to rounding issues.
- (optional) Verifies the supplied signature and extracts the address of spender from it.
- Iterates over array of actions, checks adapter in
AdapterRegistry
, anddelegatecall
s correspondingInteractiveAdapter
with assets, amounts, and additional data as arguments (deposit, or withdraw). - Returns all the resulting tokens back to the user.
function executeActions(Action[] actions) external payable
function executeActions(Action[] actions, Approval[] approvals, bytes signature) external payable
Sends all the assets under the request of Logic contract. Adds all the transferred assets to the list of withdrawable/toBeWithdrawn/resulting tokens.
function transferApprovedAssets(Approval[] approvals) external returns (address[])
InteractiveAdapter is Adapter (abstract contract)
Base contract for protocol wrappers.
Includes all the functions required to be implemented.
Should be stateless.
Only internal constant
state variables may be used.
Deposits assets to the lending/borrow/swap/liquidity.
MUST return addresses of the assets sent back to the msg.sender
.
Withdraws assets from the lending/borrow/swap/liquidity.
MUST return addresses of the assets sent back to the msg.sender
.
The following actions array will be sent to Logic
contract:
[
{
actionType: ActionType.Withdraw,
InteractiveAdapter: <address of cDAI wrapper>,
asset: 0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,
amount: Amount({
amountType: AmountType.Relative,
value: RELATIVE_AMOUNT_BASE
}),
data: ""
},
{
actionType: ActionType.Deposit,
InteractiveAdapter: <address of chai wrapper>,
asset: 0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,
amount: Amount({
amountType: AmountType.Relative,
value: RELATIVE_AMOUNT_BASE
}),
data: ""
}
]
Logic layer should do the following:
- Call
redeem()
function withgetAssetAmount(address(this))
argument. - Approve DAI to
Chai
contract. - Call
join()
function withaddress(this)
andgetAssetAmount(address(this))
arguments. - Add Chai token to the list of withdrawable/toBeWithdrawn/resulting tokens.
This project uses Truffle and web3js for all Ethereum interactions and testing.
To add new adapter with read-only functionality, one have to inherit from Adapter
contract.
getProtocolName()
, getAssetAmount()
, and getUnderlyingRates()
functions MUST be implemented.
Note: only internal constant
state variables and internal
functions MUST be used.
getProtocolName()
function has no arguments and MUST return the name of protocol.
getAssetAmount(address,address)
function has two arguments of address
type: the first one is asset address and the second one is user address.
The function MUST return amount of given asset held on the protocol for given user.
getUnderlyingRates(address)
function has only one argument – asset address.
The function MUST return all the underlying assets and their exchange rates scaled by 1e18
.
To add new adapter with deposit/withdraw functionality, one have to inherit from
InteractiveAdapter
contract.
Then, implement deposit()
and withdraw()
functions.
Both functions MUST return addresses of the assets sent back to the msg.sender
, except for ETH.
Functions from Adapter
contract MUST be implemented as well.
npm run compile
npm run test
npm run coverage
npm run lint
npm run deploy:network
, network
is either development
or mainnet
truffle run verify ContractName@0xcontractAddress --network mainnet