Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DeHive Cluster integration into Zerion #163

Open
wants to merge 10 commits into
base: interactive-updates
Choose a base branch
from
49 changes: 49 additions & 0 deletions contracts/adapters/dehive/ClusterTokenAdapter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (C) 2020 Zerion Inc. <https://zerion.io>
//
// 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 <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: LGPL-3.0-only

pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

import { TokenAdapter } from "../TokenAdapter.sol";
import { Component } from "../../shared/Structs.sol";
import { IClusterToken } from "../../interfaces/IClusterToken.sol";

/**
* @title Token adapter for ClusterTokens.
* @dev Implementation of TokenAdapter abstract contract.
*/
contract ClusterTokenAdapter is TokenAdapter {
/**
* @return Array of Component structs with underlying tokens rates for the given token.
* @dev Implementation of TokenAdapter abstract contract function.
* @param token Cluster address
*/
function getComponents(address token) external override view returns (Component[] memory) {
address[] memory underlyings = IClusterToken(token).getUnderlyings();
uint256[] memory underlyingsShares = IClusterToken(token).getUnderlyingInCluster();

Component[] memory components = new Component[](underlyings.length);
for(uint256 i = 0; i < underlyings.length; i++) {
components[i] = Component({
token: underlyings[i],
rate: int256(underlyingsShares[i] * 1e18 / 1e6)
});
}

return components;
}
}
36 changes: 36 additions & 0 deletions contracts/adapters/dehive/DeHiveProtocolAdapter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (C) 2020 Zerion Inc. <https://zerion.io>
//
// 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 <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: LGPL-3.0-only

pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

import { ERC20 } from "../../interfaces/ERC20.sol";
import { ProtocolAdapter } from "../ProtocolAdapter.sol";

/**
* @title Cluster adapter for DeHive protocol.
* @dev Implementation of ProtocolAdapter abstract contract.
*/
contract DeHiveProtocolAdapter is ProtocolAdapter {
/**
* @dev MUST return amount and type of the given token
* locked on the protocol by the given account.
*/
function getBalance(address token, address account) public override view returns (int256) {
return int256(ERC20(token).balanceOf(account));
}
}
51 changes: 51 additions & 0 deletions contracts/adapters/dehive/StakingDHVAdapter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (C) 2020 Zerion Inc. <https://zerion.io>
//
// 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 <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: LGPL-3.0-only

pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

import { ProtocolAdapter } from "../ProtocolAdapter.sol";
import { IStakingPools } from "../../interfaces/IStakingPools.sol";

/**
* @title DHV Staking adapter for DeHive protocol.
* @dev Implementation of ProtocolAdapter abstract contract.
*/
contract StakingDHVAdapter is ProtocolAdapter {
/**
* @dev MUST return amount and type of the given token
* locked on the protocol by the given account.
* @param token DHV address
* @param account User's account
*/
function getBalance(address token, address account) public override view returns (int256) {
address STAKING_DHV_ETH = address(0x04595f9010F79422a9b411ef963e4dd1F7107704);
address DHV_TOKEN_ETH = address(0x62Dc4817588d53a056cBbD18231d91ffCcd34b2A);

address STAKING_DHV_POLY = address(0x88cFC1bc9aEb80f6C8f5d310d6C3761c2a646Df7);
address DHV_TOKEN_POLY = address(0x5fCB9de282Af6122ce3518CDe28B7089c9F97b26);

uint256 amount = 0;
if (token == DHV_TOKEN_ETH) {
amount = IStakingPools(STAKING_DHV_ETH).userInfo(0, account);
}
else if (token == DHV_TOKEN_POLY) {
amount = IStakingPools(STAKING_DHV_POLY).userInfo(0, account);
}
return int256(amount);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright (C) 2020 Zerion Inc. <https://zerion.io>
//
// 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 <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: LGPL-3.0-only

pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

import { TokenAmount } from "../../shared/Structs.sol";
import { InteractiveAdapter } from "../InteractiveAdapter.sol";
import { ERC20 } from "../../interfaces/ERC20.sol";
import { SafeERC20 } from "../../shared/SafeERC20.sol";

import { DeHiveProtocolAdapter } from "../../adapters/dehive/DeHiveProtocolAdapter.sol";

import { IExternalAdapter } from "../../interfaces/IExternalAdapter.sol";

/**
* @title Interactive adapter for DeHive protocol.
* @dev Implementation of InteractiveAdapter abstract contract.
*/

contract ClusterTokenInteractiveAdapterBSC is InteractiveAdapter, DeHiveProtocolAdapter {
using SafeERC20 for ERC20;

address internal constant EXTERNAL_ADAPTER = address(0x92450c9Dc4c709F4169f9196E908772744D89C8c);
/**
* @notice Deposits tokens to the DeHive ClusterToken.
* @param tokenAmounts Array with one element - TokenAmount struct with
* ETH address, ETH amount to be deposited, and amount type.
* @param data ABI-encoded additional parameters:
* - clusterToken - ClusterToken address.
* @return tokensToBeWithdrawn Array with two elements - ETH and ClusterToken address.
* @dev Implementation of InteractiveAdapter function.
*/

function deposit(TokenAmount[] calldata tokenAmounts, bytes calldata data)
external
payable
override
returns (address[] memory tokensToBeWithdrawn)
{
require(tokenAmounts.length == 1, "DeHive: should be one token[1]");
require(tokenAmounts[0].token == ETH, "DeHive: should be ETH[2]");

address clusterToken = abi.decode(data, (address));
uint256 amount = getAbsoluteAmountDeposit(tokenAmounts[0]);

tokensToBeWithdrawn = new address[](2);
tokensToBeWithdrawn[0] = clusterToken;
tokensToBeWithdrawn[1] = ETH;

// solhint-disable-next-line no-empty-blocks
try IExternalAdapter(EXTERNAL_ADAPTER).deposit{value: amount}(clusterToken) {} catch Error(string memory reason) {
revert(reason);
} catch {
revert("DeHive: deposit fail");
}
}

/**
* @notice Withdraws tokens from the DeHive protocol.
* @param tokenAmounts Array with one element - TokenAmount struct with
* ClusterToken address, ClusterToken amount to be redeemed, and amount type.
* @return tokensToBeWithdrawn Array with one element - ETH address.
* @dev Implementation of InteractiveAdapter function.
*/

function withdraw(TokenAmount[] calldata tokenAmounts, bytes calldata data)
external
payable
override
returns (address[] memory tokensToBeWithdrawn)
{
require(tokenAmounts.length == 1, "DeHive: should be 1 tokenAmount[3]");

address clusterToken = tokenAmounts[0].token;
uint256 amount = getAbsoluteAmountWithdraw(tokenAmounts[0]);

tokensToBeWithdrawn = new address[](1);
tokensToBeWithdrawn[0] = ETH;

ERC20(clusterToken).safeApprove(EXTERNAL_ADAPTER, amount, "DeHive");
// solhint-disable-next-line no-empty-blocks
try IExternalAdapter(EXTERNAL_ADAPTER).withdraw(clusterToken, amount) {} catch Error(string memory reason) {
revert(reason);
} catch {
revert("DeHive: withdraw fail");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright (C) 2020 Zerion Inc. <https://zerion.io>
//
// 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 <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: LGPL-3.0-only

pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

import { TokenAmount } from "../../shared/Structs.sol";
import { InteractiveAdapter } from "../InteractiveAdapter.sol";
import { ERC20 } from "../../interfaces/ERC20.sol";
import { SafeERC20 } from "../../shared/SafeERC20.sol";

import { DeHiveProtocolAdapter } from "../../adapters/dehive/DeHiveProtocolAdapter.sol";

import { IExternalAdapter } from "../../interfaces/IExternalAdapter.sol";

/**
* @title Interactive adapter for DeHive protocol.
* @dev Implementation of InteractiveAdapter abstract contract.
*/

contract ClusterTokenInteractiveAdapterETH is InteractiveAdapter, DeHiveProtocolAdapter {
using SafeERC20 for ERC20;

address internal constant EXTERNAL_ADAPTER = address(0xE45713a2D7d87bd7A55d84da55aEb9EC21067870);
/**
* @notice Deposits tokens to the DeHive ClusterToken.
* @param tokenAmounts Array with one element - TokenAmount struct with
* ETH address, ETH amount to be deposited, and amount type.
* @param data ABI-encoded additional parameters:
* - clusterToken - ClusterToken address.
* @return tokensToBeWithdrawn Array with two elements - ETH and ClusterToken address.
* @dev Implementation of InteractiveAdapter function.
*/

function deposit(TokenAmount[] calldata tokenAmounts, bytes calldata data)
external
payable
override
returns (address[] memory tokensToBeWithdrawn)
{
require(tokenAmounts.length == 1, "DeHive: should be one token[1]");
require(tokenAmounts[0].token == ETH, "DeHive: should be ETH[2]");

address clusterToken = abi.decode(data, (address));
uint256 amount = getAbsoluteAmountDeposit(tokenAmounts[0]);

tokensToBeWithdrawn = new address[](2);
tokensToBeWithdrawn[0] = clusterToken;
tokensToBeWithdrawn[1] = ETH;

// solhint-disable-next-line no-empty-blocks
try IExternalAdapter(EXTERNAL_ADAPTER).deposit{value: amount}(clusterToken) {} catch Error(string memory reason) {
revert(reason);
} catch {
revert("DeHive: deposit fail");
}
}

/**
* @notice Withdraws tokens from the DeHive protocol.
* @param tokenAmounts Array with one element - TokenAmount struct with
* ClusterToken address, ClusterToken amount to be redeemed, and amount type.
* @return tokensToBeWithdrawn Array with one element - ETH address.
* @dev Implementation of InteractiveAdapter function.
*/

function withdraw(TokenAmount[] calldata tokenAmounts, bytes calldata data)
external
payable
override
returns (address[] memory tokensToBeWithdrawn)
{
require(tokenAmounts.length == 1, "DeHive: should be 1 tokenAmount[3]");

address clusterToken = tokenAmounts[0].token;
uint256 amount = getAbsoluteAmountWithdraw(tokenAmounts[0]);

tokensToBeWithdrawn = new address[](1);
tokensToBeWithdrawn[0] = ETH;

ERC20(clusterToken).safeApprove(EXTERNAL_ADAPTER, amount, "DeHive");
// solhint-disable-next-line no-empty-blocks
try IExternalAdapter(EXTERNAL_ADAPTER).withdraw(clusterToken, amount) {} catch Error(string memory reason) {
revert(reason);
} catch {
revert("DeHive: withdraw fail");
}
}
}
Loading