diff --git a/README.md b/README.md
index 5e686096..91bb5ba2 100755
--- a/README.md
+++ b/README.md
@@ -230,6 +230,7 @@ All the deployed contracts' addresses are available [here](../../wiki/Addresses)
| [Synthetix](./contracts/adapters/synthetix) | Synthetic assets protocol. Asset adapter returns amount of SNX locked as collateral. | [Asset adapter](./contracts/adapters/synthetix/SynthetixAssetAdapter.sol)
[Debt adapter](./contracts/adapters/synthetix/SynthetixDebtAdapter.sol) | — |
| [TokenSets](./contracts/adapters/tokenSets) | Automated asset management strategies. | [Asset adapter](./contracts/adapters/tokenSets/TokenSetsAdapter.sol)
[Asset adapter V2](./contracts/adapters/tokenSets/TokenSetsV2Adapter.sol) | ["SetToken"](./contracts/adapters/tokenSets/TokenSetsTokenAdapter.sol)
["SetToken V2"](./contracts/adapters/tokenSets/TokenSetsV2TokenAdapter.sol) |
| [Unagii](./contracts/adapters/unagii) | DeFi yields on auto-pilot. | [Asset adapter](./contracts/adapters/unagii/UnagiiVaultAdapter.sol) | — |
+| [Unagii V2](./contracts/adapters/unagii) | DeFi yields on auto-pilot. | [Asset adapter](./contracts/adapters/unagii/UnagiiVaultV2Adapter.sol) | — |
| [Uniswap V1](./contracts/adapters/uniswap) | Automated liquidity protocol. | [Asset adapter](./contracts/adapters/uniswap/UniswapV1Adapter.sol) supports all Uniswap V1 pools | ["Uniswap V1 pool token"](./contracts/adapters/uniswap/UniswapV1TokenAdapter.sol) |
| [Uniswap V2](./contracts/adapters/uniswap) | Automated liquidity protocol. | [Asset adapter](./contracts/adapters/uniswap/UniswapV2Adapter.sol) supports all Uniswap V2 pools | ["Uniswap V2 pool token"](./contracts/adapters/uniswap/UniswapV2TokenAdapter.sol) |
| [0x Staking](./contracts/adapters/zrx) | Liquidity rewards for staking ZRX. | [Asset adapter](./contracts/adapters/zrx/ZrxAdapter.sol) | — |
diff --git a/contracts/adapters/unagii/UnagiiVaultV2Adapter.sol b/contracts/adapters/unagii/UnagiiVaultV2Adapter.sol
new file mode 100644
index 00000000..333e7446
--- /dev/null
+++ b/contracts/adapters/unagii/UnagiiVaultV2Adapter.sol
@@ -0,0 +1,46 @@
+// Copyright (C) 2020 Zerion Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+pragma solidity 0.6.5;
+pragma experimental ABIEncoderV2;
+
+import { ERC20 } from "../../ERC20.sol";
+import { ProtocolAdapter } from "../ProtocolAdapter.sol";
+
+interface UnagiiVaultV2 {
+ function uToken() external view returns (address);
+}
+
+/**
+ * @title Adapter for Unagii V2 protocol.
+ * @dev Implementation of ProtocolAdapter interface.
+ * @author Igor Sobolev
+ */
+contract UnagiiVaultV2Adapter is ProtocolAdapter {
+
+ string public constant override adapterType = "Asset";
+
+ string public constant override tokenType = "UnagiiV2 token";
+
+ /**
+ * @return Amount of Unagii Vault V2 Tokens owned by the given account.
+ * @param token Address of the vault token.
+ * @dev Implementation of ProtocolAdapter interface function.
+ */
+ function getBalance(address token, address account) external view override returns (uint256) {
+ address uToken = UnagiiVaultV2(token).uToken();
+ return ERC20(uToken).balanceOf(account);
+ }
+}
diff --git a/contracts/adapters/unagii/UnagiiVaultV2TokenAdapter.sol b/contracts/adapters/unagii/UnagiiVaultV2TokenAdapter.sol
new file mode 100644
index 00000000..0fc4ae34
--- /dev/null
+++ b/contracts/adapters/unagii/UnagiiVaultV2TokenAdapter.sol
@@ -0,0 +1,67 @@
+// Copyright (C) 2020 Zerion Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+pragma solidity 0.6.5;
+pragma experimental ABIEncoderV2;
+
+import { ERC20 } from "../../ERC20.sol";
+import { TokenMetadata, Component } from "../../Structs.sol";
+import { TokenAdapter } from "../TokenAdapter.sol";
+
+interface UnagiiVaultV2 {
+ function token() external view returns (address);
+
+ function calcWithdraw(uint256) external view returns (uint256);
+}
+
+/**
+ * @title Token adapter for Unagii Vaults V2.
+ * @dev Implementation of TokenAdapter interface.
+ * @author Igor Sobolev
+ */
+contract UnagiiVaultV2TokenAdapter is TokenAdapter {
+
+ /**
+ * @return TokenMetadata struct with ERC20-style token info.
+ * @dev Implementation of TokenAdapter interface function.
+ */
+ function getMetadata(address token) external view override returns (TokenMetadata memory) {
+ return TokenMetadata({
+ token: token,
+ name: ERC20(token).name(),
+ symbol: ERC20(token).symbol(),
+ decimals: ERC20(token).decimals()
+ });
+ }
+
+ /**
+ * @return Array of Component structs with underlying tokens rates for the given token.
+ * @dev Implementation of TokenAdapter abstract contract function.
+ */
+ function getComponents(address token) external view override returns (Component[] memory) {
+ address underlying = UnagiiVaultV2(token).token();
+ uint256 pricing = UnagiiVaultV2(token).calcWithdraw(1e18);
+
+ Component[] memory underlyingTokens = new Component[](1);
+
+ underlyingTokens[0] = Component({
+ token: underlying,
+ tokenType: "ERC20",
+ rate: pricing
+ });
+
+ return underlyingTokens;
+ }
+}
diff --git a/migrations_scripts/1_deploy_registry_and_add_adapters.js b/migrations_scripts/1_deploy_registry_and_add_adapters.js
index b430c18a..c73ba9ed 100755
--- a/migrations_scripts/1_deploy_registry_and_add_adapters.js
+++ b/migrations_scripts/1_deploy_registry_and_add_adapters.js
@@ -98,6 +98,8 @@ const UniswapV1TokenAdapter = artifacts.require('UniswapV1TokenAdapter');
const UniswapV2TokenAdapter = artifacts.require('UniswapV2TokenAdapter');
const UnagiiVaultAdapter = artifacs.require('UnagiiVaultAdapter');
const UnagiiVaultTokenAdapter = artifacs.require('UnagiiVaultTokenAdapter');
+const UnagiiVaultV2Adapter = artifacs.require('UnagiiVaultV2Adapter');
+const UnagiiVaultV2TokenAdapter = artifacs.require('UnagiiVaultV2TokenAdapter');
const AdapterRegistry = artifacts.require('AdapterRegistry');
const antAddress = '0x960b236A07cf122663c4303350609A66A7B288C0';
@@ -454,6 +456,12 @@ const unagiiVaultUSDTAddress = '0x178Bf8fD04b47D2De3eF3f6b3D112106375ad584';
const unagiiVaultWBTCAddress = '0x3aF5Ba94C29a8407785f5f6d90eF5d69a8EB2436';
const unagiiVaultETHAddress = '0x77607588222e01bf892a29Abab45796A2047fc7b';
+const unagiiVaultV2USDCAddress = '0x7f75d72886D6A8677321E5602d18948aBCb4281A';
+const unagiiVaultV2DAIAddress = '0x9ce3018375d305CE3C3303A26eF62D3d2EB8561A';
+const unagiiVaultV2USDTAddress = '0x1Eb06EaE3263a35619dC87812a8e7Ec811B59E63';
+const unagiiVaultV2WBTCAddress = '0xB088D7C71ea9eBAed981c103Fc3019B59950d2C9';
+const unagiiVaultV2ETHAddress = '0x8eF11c51a666C53Aeeec504f120cd1435E451342';
+
const aaveAssetAdapterTokens = [
aDaiAddress,
aTusdAddress,
@@ -979,6 +987,14 @@ const unagiiVaultAdapterTokens = [
unagiiVaultETHAddress,
];
+const unagiiVaultV2AdapterTokens = [
+ unagiiVaultV2USDCAddress,
+ unagiiVaultV2DAIAddress,
+ unagiiVaultV2USDTAddress,
+ unagiiVaultV2WBTCAddress,
+ unagiiVaultV2ETHAddress,
+];
+
let protocolNames = [];
let metadata = [];
let adapters = [];
@@ -1635,6 +1651,18 @@ module.exports = async (deployer, network, accounts) => {
'0',
]);
+ await deployer.deploy(UnagiiVaultV2Adapter, { from: accounts[0] });
+ adapters.push([UnagiiVaultV2Adapter.address]);
+ tokens.push([unagiiVaultV2AdapterTokens]);
+ protocolNames.push('Unagii V2');
+ metadata.push([
+ 'Unagii V2',
+ 'DeFi yields on auto-pilot.',
+ 'unagii.com',
+ 'protocol-icons.s3.amazonaws.com/unagii.png',
+ '0',
+ ]);
+
await deployer.deploy(ERC20TokenAdapter, { from: accounts[0] })
.then(() => {
tokenAdapters.push(
@@ -1785,6 +1813,12 @@ module.exports = async (deployer, network, accounts) => {
UnagiiVaultTokenAdapter.address,
);
});
+ await deployer.deploy(UnagiiVaultV2TokenAdapter, { from: accounts[0] })
+ .then(() => {
+ tokenAdapters.push(
+ UnagiiVaultV2TokenAdapter.address,
+ );
+ });
await deployer.deploy(LinkswapTokenAdapter, { from: accounts[0] })
.then(() => {
tokenAdapters.push(
diff --git a/test/UnagiiV2Adapter.js b/test/UnagiiV2Adapter.js
new file mode 100644
index 00000000..ec37bf97
--- /dev/null
+++ b/test/UnagiiV2Adapter.js
@@ -0,0 +1,41 @@
+const TokenAdapter = artifacts.require('UnagiiVaultTokenAdapter');
+
+contract('UnagiiVaultTokenAdapter', () => {
+ const uDAIV2Address = '0x9ce3018375d305CE3C3303A26eF62D3d2EB8561A';
+ const daiAddress = '0x6B175474E89094C44Da98b954EedeAC495271d0F';
+
+ let accounts;
+ let tokenAdapter;
+ const uDAIV2 = [
+ uDAIV2Address,
+ 'unagii_Dai Stablecoin_v2',
+ 'uDAIv2',
+ '18',
+ ];
+
+ beforeEach(async () => {
+ accounts = await web3.eth.getAccounts();
+
+ await TokenAdapter.new({ from: accounts[0] })
+ .then((result) => {
+ tokenAdapter = result.contract;
+ });
+ });
+
+ it('should return correct components', async () => {
+ await tokenAdapter.methods['getComponents(address)'](uDAIV2Address)
+ .call()
+ .then((result) => {
+ assert.equal(result[0][0], daiAddress);
+ assert.equal(result[0][1], 'ERC20');
+ });
+ });
+
+ it('should return correct metadata', async () => {
+ await tokenAdapter.methods['getMetadata(address)'](uDAIV2Address)
+ .call()
+ .then((result) => {
+ assert.deepEqual(result, uDAIV2);
+ });
+ });
+});