Skip to content

Commit d598340

Browse files
authored
Merge pull request #24 from bugduino/add-idle-finance
NEW: add Idle finance adapters
2 parents d670a52 + 0f5a9bf commit d598340

File tree

6 files changed

+271
-33
lines changed

6 files changed

+271
-33
lines changed

README.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,21 @@
1010
[![Discord](https://img.shields.io/discord/544761450724458498?label=discord)](https://go.zerion.io/discord)
1111
[![Twitter Follow](https://img.shields.io/twitter/follow/zerion_io.svg)](https://twitter.com/intent/follow?screen_name=zerion_io)
1212

13-
**DeFi SDK** is an open-source system of smart contracts designed for precise DeFi portfolio accounting. To put it simply, DeFi SDK is the on-chain *balanceOf* for DeFi protocols.
13+
**DeFi SDK** is an open-source system of smart contracts designed for precise DeFi portfolio accounting. To put it simply, DeFi SDK is the on-chain *balanceOf* for DeFi protocols.
1414

1515
If you have any questions about DeFi SDK, feel free to reach out to us on our [Discord server](https://go.zerion.io/discord).
1616

1717
## Features
1818

19+
1920
#### 💥Query user assets and debt deposited in DeFi protocols like *Maker, Aave, dYdX*, etc.
20-
> How much debt does `0xdead..beef` have on Compound?
21+
> How much debt does `0xdead..beef` have on Compound?
2122
#### 📊Get the underlying components of complex derivative ERC20 tokens
2223
> How much `cUSDC` vs `ETH` does `ETHMACOAPY` have?
2324
#### ✨Interact with multiple DeFi protocols in a unified way (coming soon)
2425
> See [What’s next for DeFi SDK](#whats-next-for-defi-sdk-)
2526
26-
## Table of Contents
27+
## Table of Contents
2728

2829
- [Examples](#examples)
2930
- [DeFi SDK architecture](#defi-sdk-architecture)
@@ -32,7 +33,7 @@ If you have any questions about DeFi SDK, feel free to reach out to us on our [D
3233
- [What’s next for DeFi SDK](#whats-next-for-defi-sdk-)
3334
- [Security vulnerabilities](#security-vulnerabilities-)
3435

35-
## Examples
36+
## Examples
3637

3738
### Fetch Compound debt and collateral
3839

@@ -141,26 +142,27 @@ and obtain all balances for a given account. The response from the smart-contrac
141142

142143
## DeFi SDK architecture
143144

144-
- **ProtocolAdapter** is a special contract for every protocol. Its main purpose is to wrap all the protocol interactions.
145+
- **ProtocolAdapter** is a special contract for every protocol. Its main purpose is to wrap all the protocol interactions.
145146
There are different types of protocol adapters: "Asset" adapter returns the amount of the account's tokens held on the protocol and the "Debt" adapter returns the amount of the account's debt to the protocol. Some protocols do not use "simple" ERC20 tokens but instead have complex derivatives, for example the Compound protocol has CTokens. The **ProtocolAdapter** contract also provides information about the type of tokens used within it.
146-
- **TokenAdapter** is a contract for every derivative token type (e.g cTokens, aTokens, yTokens, etc.)
147+
- **TokenAdapter** is a contract for every derivative token type (e.g cTokens, aTokens, yTokens, etc.)
147148
Its main purpose is to provide ERC20-style token metadata as well as information about the underlying ERC20 tokens (like DAI for cDAI). Namely, it provides addresses, types and rates of underlying tokens.
148-
- **AdapterRegistry** is a contract that a) maintains a list of *ProtocolAdapters* and *TokenAdapters* and b) is called to fetch user balances.
149+
- **AdapterRegistry** is a contract that a) maintains a list of *ProtocolAdapters* and *TokenAdapters* and b) is called to fetch user balances.
149150

150151
More detailed documentation about contracts can be found in [adapters](../../wiki/Adapters) and [AdapterRegistry](../../wiki/AdapterRegistry) documentation.
151152

152-
## Supported protocols
153+
## Supported protocols
153154

154155
| Protocol Name | Description | Protocol Adapters | Token Adapters |
155156
| :-----------: | :---------: | :---------------: | :------------: |
156157
| [Aave](./contracts/adapters/aave) | Decentralized lending & borrowing protocol. | [Asset adapter](./contracts/adapters/aave/AaveAssetAdapter.sol) <br> [Debt adapter](contracts/adapters/aave/AaveDebtAdapter.sol) | ["AToken"](./contracts/adapters/aave/AaveTokenAdapter.sol) |
157158
| [Compound](./contracts/adapters/compound) | Decentralized lending & borrowing protocol. | [Asset adapter](./contracts/adapters/compound/CompoundAssetAdapter.sol) <br> [Debt adapter](./contracts/adapters/compound/CompoundDebtAdapter.sol) | ["CToken"](./contracts/adapters/compound/CompoundTokenAdapter.sol) |
158159
| [Curve](./contracts/adapters/curve) | Exchange liquidity pool for stablecoin trading. Supports Compound, Y, and BUSD pools. | [Asset adapter](./contracts/adapters/curve/CurveAdapter.sol) | ["Curve pool token"](contracts/adapters/curve/CurveTokenAdapter.sol) |
159160
| [dYdX](./contracts/adapters/dydx) | Decentralized trading platform. All 4 markets (WETH, SAI, USDC, DAI) are supported. | [Asset adapter](./contracts/adapters/dydx/DyDxAssetAdapter.sol) <br> [Debt adapter](./contracts/adapters/dydx/DyDxDebtAdapter.sol) ||
161+
| [Idle](./contracts/adapters/idle) | Yield aggregator for lending platforms. | [Asset adapter](./contracts/adapters/idle/IdleAdapter.sol) | ["IdleToken"](./contracts/adapters/idle/IdleTokenAdapter.sol) |
160162
| [iearn.finance (v2/v3)](./contracts/adapters/iearn) | Yield aggregator for lending platforms. Protocol adapter is duplicated for v2 and v3 versions of protocol. | [Asset adapter](./contracts/adapters/iearn/IearnAdapter.sol) | ["YToken"](./contracts/adapters/iearn/IearnTokenAdapter.sol) |
161163
| [Chai](./contracts/adapters/maker) | A simple ERC20 wrapper over the Dai Savings Rate. | [Asset adapter](./contracts/adapters/maker/ChaiAdapter.sol) | ["Chai token"](./contracts/adapters/maker/ChaiTokenAdapter.sol) |
162164
| [DSR](./contracts/adapters/maker) | Decentralized lending protocol by MakerDAO. | [Asset adapter](./contracts/adapters/maker/DSRAdapter.sol) ||
163-
| [MCD](./contracts/adapters/maker) | Collateralized loans on Maker. | [Asset adapter](./contracts/adapters/maker/MCDAssetAdapter.sol) <br> [Debt adapter](./contracts/adapters/maker/MCDDebtAdapter.sol) ||
165+
| [MCD](./contracts/adapters/maker) | Collateralized loans on Maker. | [Asset adapter](./contracts/adapters/maker/MCDAssetAdapter.sol) <br> [Debt adapter](./contracts/adapters/maker/MCDDebtAdapter.sol) ||
164166
| [PoolTogether](./contracts/adapters/poolTogether) | Decentralized no-loss lottery. Supports SAI, DAI, and USDC pools. | [Asset adapter](./contracts/adapters/poolTogether/PoolTogetherAdapter.sol) | ["PoolTogether pool"](./contracts/adapters/poolTogether/PoolTogetherTokenAdapter.sol) |
165167
| [Synthetix](./contracts/adapters/synthetix) | Synthetic assets protocol. Asset adapter returns amount of SNX locked as collateral. | [Asset adapter](./contracts/adapters/synthetix/SynthetixAssetAdapter.sol) <br> [Debt adapter](./contracts/adapters/synthetix/SynthetixDebtAdapter.sol) ||
166168
| [Uniswap V1](./contracts/adapters/uniswap) | Automated liquidity protocol. Top 30 pools are added to the **AdapterRegistry** contract, however adapter supports all Uniswap pools. | [Asset adapter](./contracts/adapters/uniswap/UniswapV1Adapter.sol) supports all Uniswap pools | ["Uniswap V1 pool token"](./contracts/adapters/uniswap/UniswapV1TokenAdapter.sol) |
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright (C) 2020 Zerion Inc. <https://zerion.io>
2+
//
3+
// This program is free software: you can redistribute it and/or modify
4+
// it under the terms of the GNU General Public License as published by
5+
// the Free Software Foundation, either version 3 of the License, or
6+
// (at your option) any later version.
7+
//
8+
// This program is distributed in the hope that it will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
// GNU General Public License for more details.
12+
//
13+
// You should have received a copy of the GNU General Public License
14+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
15+
16+
pragma solidity 0.6.4;
17+
pragma experimental ABIEncoderV2;
18+
19+
import { ProtocolAdapter } from "../ProtocolAdapter.sol";
20+
import { ERC20 } from "../../ERC20.sol";
21+
22+
23+
/**
24+
* @title Adapter for idle.finance protocol.
25+
* @dev Implementation of ProtocolAdapter interface.
26+
* @author William Bergamo <[email protected]>
27+
*/
28+
contract IdleAdapter is ProtocolAdapter {
29+
30+
/**
31+
* @return Type of the adapter.
32+
* @dev Implementation of ProtocolAdapter interface function.
33+
*/
34+
function adapterType() external pure override returns (string memory) {
35+
return "Asset";
36+
}
37+
38+
/**
39+
* @return Type of the token used in adapter.
40+
* @dev Implementation of ProtocolAdapter interface function.
41+
*/
42+
function tokenType() external pure override returns (string memory) {
43+
return "IdleToken";
44+
}
45+
46+
/**
47+
* @return Amount of IdleTokens held by the given account.
48+
* @dev Implementation of ProtocolAdapter interface function.
49+
*/
50+
function getBalance(address token, address account) external view override returns (uint256) {
51+
return ERC20(token).balanceOf(account);
52+
}
53+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright (C) 2020 Zerion Inc. <https://zerion.io>
2+
//
3+
// This program is free software: you can redistribute it and/or modify
4+
// it under the terms of the GNU General Public License as published by
5+
// the Free Software Foundation, either version 3 of the License, or
6+
// (at your option) any later version.
7+
//
8+
// This program is distributed in the hope that it will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
// GNU General Public License for more details.
12+
//
13+
// You should have received a copy of the GNU General Public License
14+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
15+
16+
pragma solidity 0.6.4;
17+
pragma experimental ABIEncoderV2;
18+
19+
import { TokenAdapter } from "../TokenAdapter.sol";
20+
import { TokenMetadata, Component } from "../../Structs.sol";
21+
import { ERC20 } from "../../ERC20.sol";
22+
23+
24+
/**
25+
* @dev IdleToken contract interface.
26+
* Only the functions required for IdleTokenAdapter contract are added.
27+
* The IdleToken contracts are available here
28+
* https://github.com/bugduino/idle-contracts/blob/master/contracts/IdleToken.sol
29+
* @author William Bergamo <[email protected]>
30+
*/
31+
interface IdleToken {
32+
function token() external view returns (address);
33+
function tokenPrice() external view returns (uint256);
34+
}
35+
36+
37+
/**
38+
* @title Token adapter for IdleTokens.
39+
* @dev Implementation of TokenAdapter interface.
40+
*/
41+
contract IdleTokenAdapter is TokenAdapter {
42+
43+
/**
44+
* @return TokenMetadata struct with ERC20-style token info.
45+
* @dev Implementation of TokenAdapter interface function.
46+
*/
47+
function getMetadata(address token) external view override returns (TokenMetadata memory) {
48+
return TokenMetadata({
49+
token: token,
50+
name: ERC20(token).name(),
51+
symbol: ERC20(token).symbol(),
52+
decimals: ERC20(token).decimals()
53+
});
54+
}
55+
56+
/**
57+
* @return Array of Component structs with underlying tokens rates for the given asset.
58+
* @dev Implementation of TokenAdapter interface function.
59+
*/
60+
function getComponents(address token) external view override returns (Component[] memory) {
61+
Component[] memory underlyingTokens = new Component[](1);
62+
63+
underlyingTokens[0] = Component({
64+
token: IdleToken(token).token(),
65+
tokenType: "ERC20",
66+
rate: IdleToken(token).tokenPrice()
67+
});
68+
69+
return underlyingTokens;
70+
}
71+
}

migrations_scripts/1_use_registry_and_add_adapters.js

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ const yUSDCv3 = '0x26EA744E5B887E5205727f55dFBE8685e3b21951';
6565
const yUSDTv3 = '0xE6354ed5bC4b393a5Aad09f21c46E101e692d447';
6666
const yBUSDv3 = '0x04bC0Ab673d88aE9dbC9DA2380cB6B79C4BCa9aE';
6767

68+
const idleDAI = '0x10eC0D497824e342bCB0EDcE00959142aAa766dD';
69+
const idleUSDC = '0xeB66ACc3d011056B00ea521F8203580C2E5d3991';
6870

6971
const ssCompoundTokenAddress = '0x845838DF265Dcd2c412A1Dc9e959c7d08537f8a2';
7072
const ssYTokenAddress = '0xdF5e0e81Dff6FAF3A7e52BA697820c5e32D806A8';
@@ -141,6 +143,10 @@ const iearn3AdapterTokens = [
141143
yUSDTv3,
142144
yBUSDv3,
143145
];
146+
const idleAdapterTokens = [
147+
idleDAI,
148+
idleUSDC
149+
];
144150
const dsrAdapterTokens = [
145151
daiAddress,
146152
];
@@ -202,8 +208,8 @@ const zrxAdapterTokens = [
202208

203209
let protocolNames = [];
204210
let metadata = [];
205-
let adapters = [[], [], [], [], [], [], [], [], [], [], [], [], []];
206-
let tokens = [[], [], [], [], [], [], [], [], [], [], [], [], []];
211+
let adapters = [[], [], [], [], [], [], [], [], [], [], [], [], [], []];
212+
let tokens = [[], [], [], [], [], [], [], [], [], [], [], [], [], []];
207213
let tokenAdapters = [];
208214

209215
module.exports = async (deployer, network, accounts) => {
@@ -274,10 +280,23 @@ module.exports = async (deployer, network, accounts) => {
274280
'protocol-icons.s3.amazonaws.com/dYdX.png',
275281
'0',
276282
]);
283+
await deployer.deploy(IdleAdapter, { from: accounts[0] })
284+
.then(() => {
285+
adapters[4].push(IdleAdapter.address);
286+
tokens[4].push(idleAdapterTokens);
287+
});
288+
protocolNames.push('Idle');
289+
metadata.push([
290+
'Idle',
291+
'Yield aggregator for lending platforms',
292+
'idle.finance',
293+
'protocol-icons.s3.amazonaws.com/idle.png',
294+
'0',
295+
]);
277296
await deployer.deploy(IearnAdapter, { from: accounts[0] })
278297
.then(() => {
279-
adapters[4].push(IearnAdapter.address);
280-
tokens[4].push(iearn2AdapterTokens);
298+
adapters[5].push(IearnAdapter.address);
299+
tokens[5].push(iearn2AdapterTokens);
281300
});
282301
protocolNames.push('iearn.finance (v2)');
283302
metadata.push([
@@ -289,8 +308,8 @@ module.exports = async (deployer, network, accounts) => {
289308
]);
290309
await deployer.deploy(IearnAdapter, { from: accounts[0] })
291310
.then(() => {
292-
adapters[5].push(IearnAdapter.address);
293-
tokens[5].push(iearn3AdapterTokens);
311+
adapters[6].push(IearnAdapter.address);
312+
tokens[6].push(iearn3AdapterTokens);
294313
});
295314
protocolNames.push('iearn.finance (v3)');
296315
metadata.push([
@@ -302,8 +321,8 @@ module.exports = async (deployer, network, accounts) => {
302321
]);
303322
await deployer.deploy(ChaiAdapter, { from: accounts[0] })
304323
.then(() => {
305-
adapters[6].push(ChaiAdapter.address);
306-
tokens[6].push(chaiAdapterTokens);
324+
adapters[7].push(ChaiAdapter.address);
325+
tokens[7].push(chaiAdapterTokens);
307326
});
308327
protocolNames.push('Chai');
309328
metadata.push([
@@ -315,8 +334,8 @@ module.exports = async (deployer, network, accounts) => {
315334
]);
316335
await deployer.deploy(DSRAdapter, { from: accounts[0] })
317336
.then(() => {
318-
adapters[7].push(DSRAdapter.address);
319-
tokens[7].push(dsrAdapterTokens);
337+
adapters[8].push(DSRAdapter.address);
338+
tokens[8].push(dsrAdapterTokens);
320339
});
321340
protocolNames.push('Dai Savings Rate');
322341
metadata.push([
@@ -328,13 +347,13 @@ module.exports = async (deployer, network, accounts) => {
328347
]);
329348
await deployer.deploy(MCDAssetAdapter, { from: accounts[0] })
330349
.then(() => {
331-
adapters[8].push(MCDAssetAdapter.address);
332-
tokens[8].push(mcdAssetAdapterTokens);
350+
adapters[9].push(MCDAssetAdapter.address);
351+
tokens[9].push(mcdAssetAdapterTokens);
333352
});
334353
await deployer.deploy(MCDDebtAdapter, { from: accounts[0] })
335354
.then(() => {
336-
adapters[8].push(MCDDebtAdapter.address);
337-
tokens[8].push(mcdDebtAdapterTokens);
355+
adapters[9].push(MCDDebtAdapter.address);
356+
tokens[9].push(mcdDebtAdapterTokens);
338357
});
339358
protocolNames.push('Multi-Collateral Dai');
340359
metadata.push([
@@ -346,8 +365,8 @@ module.exports = async (deployer, network, accounts) => {
346365
]);
347366
await deployer.deploy(PoolTogetherAdapter, { from: accounts[0] })
348367
.then(() => {
349-
adapters[9].push(PoolTogetherAdapter.address);
350-
tokens[9].push(poolTogetherAdapterTokens);
368+
adapters[10].push(PoolTogetherAdapter.address);
369+
tokens[10].push(poolTogetherAdapterTokens);
351370
});
352371
protocolNames.push('PoolTogether');
353372
metadata.push([
@@ -359,13 +378,13 @@ module.exports = async (deployer, network, accounts) => {
359378
]);
360379
await deployer.deploy(SynthetixAssetAdapter, { from: accounts[0] })
361380
.then(() => {
362-
adapters[10].push(SynthetixAssetAdapter.address);
363-
tokens[10].push(synthetixAssetAdapterTokens);
381+
adapters[11].push(SynthetixAssetAdapter.address);
382+
tokens[11].push(synthetixAssetAdapterTokens);
364383
});
365384
await deployer.deploy(SynthetixDebtAdapter, { from: accounts[0] })
366385
.then(() => {
367-
adapters[10].push(SynthetixDebtAdapter.address);
368-
tokens[10].push(synthetixDebtAdapterTokens);
386+
adapters[11].push(SynthetixDebtAdapter.address);
387+
tokens[11].push(synthetixDebtAdapterTokens);
369388
});
370389
protocolNames.push('Synthetix');
371390
metadata.push([
@@ -377,8 +396,8 @@ module.exports = async (deployer, network, accounts) => {
377396
]);
378397
await deployer.deploy(UniswapV1Adapter, { from: accounts[0] })
379398
.then(() => {
380-
adapters[11].push(UniswapV1Adapter.address);
381-
tokens[11].push(uniswapV1AdapterTokens);
399+
adapters[12].push(UniswapV1Adapter.address);
400+
tokens[12].push(uniswapV1AdapterTokens);
382401
});
383402
protocolNames.push('Uniswap V1');
384403
metadata.push([
@@ -390,8 +409,8 @@ module.exports = async (deployer, network, accounts) => {
390409
]);
391410
await deployer.deploy(ZrxAdapter, { from: accounts[0] })
392411
.then(() => {
393-
adapters[12].push(ZrxAdapter.address);
394-
tokens[12].push(zrxAdapterTokens);
412+
adapters[13].push(ZrxAdapter.address);
413+
tokens[13].push(zrxAdapterTokens);
395414
});
396415
protocolNames.push('0x Staking');
397416
metadata.push([
@@ -401,6 +420,7 @@ module.exports = async (deployer, network, accounts) => {
401420
'protocol-icons.s3.amazonaws.com/0x-staking.png',
402421
'0',
403422
]);
423+
404424
await deployer.deploy(ERC20TokenAdapter, { from: accounts[0] })
405425
.then(() => {
406426
tokenAdapters.push(
@@ -431,6 +451,12 @@ module.exports = async (deployer, network, accounts) => {
431451
IearnTokenAdapter.address,
432452
);
433453
});
454+
await deployer.deploy(IdleTokenAdapter, { from: accounts[0] })
455+
.then(() => {
456+
tokenAdapters.push(
457+
IdleTokenAdapter.address,
458+
);
459+
});
434460
await deployer.deploy(ChaiTokenAdapter, { from: accounts[0] })
435461
.then(() => {
436462
tokenAdapters.push(
@@ -467,6 +493,7 @@ module.exports = async (deployer, network, accounts) => {
467493
'AToken',
468494
'CToken',
469495
'Curve pool token',
496+
'IdleToken',
470497
'YToken',
471498
'Chai token',
472499
'PoolTogether pool',

test/AdapterRegistryDeployed.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ contract.skip('AdapterRegistry deployed', () => {
2626
'Chai',
2727
'iearn.finance (v3)',
2828
'iearn.finance (v2)',
29+
'Idle',
2930
'dYdX',
3031
'Curve',
3132
'Compound',
@@ -42,6 +43,7 @@ contract.skip('AdapterRegistry deployed', () => {
4243
'Uniswap V1 pool token',
4344
'PoolTogether pool',
4445
'Chai token',
46+
'IdleToken',
4547
'YToken',
4648
'Curve pool token',
4749
'CToken',

0 commit comments

Comments
 (0)