-
Notifications
You must be signed in to change notification settings - Fork 257
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
updated curve adapter + added new one
- Loading branch information
1 parent
722a45f
commit dc0d52d
Showing
4 changed files
with
189 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
pragma solidity 0.6.2; | ||
pragma experimental ABIEncoderV2; | ||
|
||
import { Adapter } from "./Adapter.sol"; | ||
import { Component } from "../Structs.sol"; | ||
import { ERC20 } from "../ERC20.sol"; | ||
|
||
|
||
/** | ||
* @dev YToken contract interface. | ||
* Only the functions required for CurveYAdapter contract are added. | ||
* The YToken contracts are available here | ||
* https://github.com/iearn-finance/itoken/tree/master/contracts. | ||
*/ | ||
interface YToken { | ||
function token() external view returns (address); | ||
function getPricePerFullShare() external view returns (uint256); | ||
} | ||
|
||
|
||
/** | ||
* @dev stableswap contract interface. | ||
* Only the functions required for CurveYAdapter contract are added. | ||
* The stableswap contract is available here | ||
* https://github.com/curvefi/curve-contract/blob/compounded/vyper/stableswap.vy. | ||
*/ | ||
// solhint-disable-next-line contract-name-camelcase | ||
interface stableswap { | ||
function coins(int128) external view returns (address); | ||
function balances(int128) external view returns(uint256); | ||
} | ||
|
||
|
||
/** | ||
* @title Adapter for Curve protocol. | ||
* @dev Implementation of Adapter interface. | ||
*/ | ||
contract CurveYAdapter is Adapter { | ||
|
||
address constant internal SS = 0x45F783CCE6B7FF23B2ab2D70e416cdb7D6055f51; | ||
|
||
/** | ||
* @return Name of the protocol. | ||
* @dev Implementation of Adapter function. | ||
*/ | ||
function getProtocolName() external pure override returns (string memory) { | ||
return("Curve ∙ Y pool"); | ||
} | ||
|
||
/** | ||
* @return Amount of stableswapToken locked on the protocol by the given user. | ||
* @dev Implementation of Adapter function. | ||
*/ | ||
function getAssetAmount(address asset, address user) external view override returns (int256) { | ||
return int256(ERC20(asset).balanceOf(user)); | ||
} | ||
|
||
/** | ||
* @return Struct with underlying assets rates for the given asset. | ||
* @dev Implementation of Adapter function. | ||
* Repeats calculations made in stableswap contract. | ||
*/ | ||
function getUnderlyingRates(address asset) external view override returns (Component[] memory) { | ||
Component[] memory components = new Component[](4); | ||
stableswap ss = stableswap(SS); | ||
|
||
for (uint256 i = 0; i < 4; i++) { | ||
YToken yToken = YToken(ss.coins(int128(i))); | ||
components[i] = Component({ | ||
underlying: yToken.token(), | ||
rate: ss.balances(int128(i)) * yToken.getPricePerFullShare() / ERC20(asset).totalSupply() | ||
}); | ||
} | ||
|
||
return components; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
const { BN } = web3.utils; | ||
const AdapterRegistry = artifacts.require('./AdapterRegistry'); | ||
const CurveAdapter = artifacts.require('./CurveYAdapter'); | ||
|
||
contract('CurveYAdapter', () => { | ||
const ssTokenAddress = '0xdF5e0e81Dff6FAF3A7e52BA697820c5e32D806A8'; | ||
const DAIAddress = '0x6B175474E89094C44Da98b954EedeAC495271d0F'; | ||
const USDCAddress = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; | ||
const USDTAddress = '0xdAC17F958D2ee523a2206206994597C13D831ec7'; | ||
const TUSDAddress = '0x0000000000085d4780B73119b644AE5ecd22b376'; | ||
const testAddress = '0x42b9dF65B219B3dD36FF330A4dD8f327A6Ada990'; | ||
|
||
let accounts; | ||
let adapterRegistry; | ||
let curveAdapter; | ||
|
||
beforeEach(async () => { | ||
accounts = await web3.eth.getAccounts(); | ||
await CurveAdapter.new({ from: accounts[0] }) | ||
.then((result) => { | ||
curveAdapter = result.contract; | ||
}); | ||
await AdapterRegistry.new( | ||
[curveAdapter.options.address], | ||
[[ssTokenAddress]], | ||
{ from: accounts[0] }, | ||
) | ||
.then((result) => { | ||
adapterRegistry = result.contract; | ||
}); | ||
}); | ||
|
||
it('should return correct balances and rates', async () => { | ||
await adapterRegistry.methods['getBalancesAndRates(address)'](testAddress) | ||
.call() | ||
.then((result) => { | ||
const base = new BN(10).pow(new BN(18)); | ||
const ssTokenAmount = new BN(result[0].balances[0].amount); | ||
const DAIRate = new BN(result[0].rates[0].components[0].rate); | ||
const DAIAmount = DAIRate.mul(ssTokenAmount).div(base).toString(); | ||
const USDCRate = new BN(result[0].rates[0].components[1].rate); | ||
const USDCAmount = USDCRate.mul(ssTokenAmount).div(base).toString(); | ||
const USDTRate = new BN(result[0].rates[0].components[2].rate); | ||
const USDTAmount = USDTRate.mul(ssTokenAmount).div(base).toString(); | ||
const TUSDRate = new BN(result[0].rates[0].components[3].rate); | ||
const TUSDAmount = TUSDRate.mul(ssTokenAmount).div(base).toString(); | ||
|
||
// eslint-disable-next-line no-console | ||
console.log(`Deposited ssToken amount: ${ssTokenAmount.toString()}`); | ||
assert.equal(result[0].balances[0].decimals, 18); | ||
assert.equal(result[0].balances[0].asset, ssTokenAddress); | ||
assert.equal(result[0].rates[0].asset, ssTokenAddress); | ||
assert.equal(result[0].rates[0].components[0].underlying, DAIAddress); | ||
// eslint-disable-next-line no-console | ||
console.log(`DAI rate: ${DAIRate.toString()}`); | ||
// eslint-disable-next-line no-console | ||
console.log(`Means its: ${DAIAmount} DAI locked`); | ||
assert.equal(result[0].rates[0].components[1].underlying, USDCAddress); | ||
// eslint-disable-next-line no-console | ||
console.log(`USDC rate: ${USDCRate.toString()}`); | ||
// eslint-disable-next-line no-console | ||
console.log(`Means its: ${USDCAmount} USDC locked`); | ||
assert.equal(result[0].rates[0].components[2].underlying, USDTAddress); | ||
// eslint-disable-next-line no-console | ||
console.log(`USDT rate: ${USDTRate.toString()}`); | ||
// eslint-disable-next-line no-console | ||
console.log(`Means its: ${USDTAmount} USDT locked`); | ||
assert.equal(result[0].rates[0].components[3].underlying, TUSDAddress); | ||
// eslint-disable-next-line no-console | ||
console.log(`TUSD rate: ${TUSDRate.toString()}`); | ||
// eslint-disable-next-line no-console | ||
console.log(`Means its: ${TUSDAmount} TUSD locked`); | ||
assert.equal(result[0].name, 'Curve ∙ Y pool'); | ||
}); | ||
}); | ||
}); |