dsa-connectors/contracts/mainnet/connectors/ubiquity/main.sol
2021-10-22 14:06:29 +02:00

223 lines
6.0 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;
pragma abicoder v2;
/**
* @title Ubiquity.
* @dev Ubiquity Dollar (uAD).
*/
import { TokenInterface } from "../../common/interfaces.sol";
import { IUbiquityBondingV2, IUbiquityMetaPool, I3Pool } from "./interfaces.sol";
import { Helpers } from "./helpers.sol";
import { Events } from "./events.sol";
abstract contract UbiquityResolver is Helpers, Events {
/**
* @dev Deposit into Ubiquity protocol
* @notice 3POOL (DAI / USDC / USDT) => METAPOOL (3CRV / uAD) => uAD3CRV-f => Ubiquity BondingShare
* @notice STEP 1 : 3POOL (DAI / USDC / USDT) => 3CRV
* @notice STEP 2 : METAPOOL(3CRV / UAD) => uAD3CRV-f
* @notice STEP 3 : uAD3CRV-f => Ubiquity BondingShare
* @param token Token deposited : DAI, USDC, USDT, 3CRV, uAD or uAD3CRV-f
* @param amount Amount of tokens to deposit (For max: `uint256(-1)`)
* @param durationWeeks Duration in weeks tokens will be locked (4-208)
* @param getId ID to retrieve amt.
* @param setId ID stores the bonding share id of tokens deposited.
*/
function deposit(
address token,
uint256 amount,
uint256 durationWeeks,
uint256 getId,
uint256 setId
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
address UAD3CRVf = getUADCRV3();
bool[6] memory tok = [
token == DAI, // 0
token == USDC, // 1
token == USDT, // 2
token == CRV3, // 3
token == getUAD(), // 4
token == UAD3CRVf // 5
];
require(
// DAI / USDC / USDT / CRV3 / UAD / UAD3CRVF
tok[0] || tok[1] || tok[2] || tok[3] || tok[4] || tok[5],
"Invalid token: must be DAI, USDC, USDT, 3CRV, uAD or uAD3CRV-f"
);
uint256 _amount = getUint(getId, amount);
uint256 lpAmount;
// Full balance if amount = -1
if (_amount == uint256(-1)) {
_amount = getTokenBal(TokenInterface(token));
}
// STEP 1 : SwapTo3CRV : Deposit DAI, USDC or USDT into 3Pool to get 3Crv LPs
// DAI / USDC / USDT
if (tok[0] || tok[1] || tok[2]) {
uint256[3] memory amounts1;
if (tok[0]) amounts1[0] = _amount;
else if (tok[1]) amounts1[1] = _amount;
else if (tok[2]) amounts1[2] = _amount;
approve(TokenInterface(token), Pool3, _amount);
I3Pool(Pool3).add_liquidity(amounts1, 0);
}
// STEP 2 : ProvideLiquidityToMetapool : Deposit in uAD3CRV pool to get uAD3CRV-f LPs
// DAI / USDC / USDT / CRV3 / UAD
if (tok[0] || tok[1] || tok[2] || tok[3] || tok[4]) {
uint256[2] memory amounts2;
address token2 = token;
uint256 _amount2;
if (tok[4]) {
_amount2 = _amount;
amounts2[0] = _amount2;
} else {
if (tok[3]) {
_amount2 = _amount;
} else {
token2 = CRV3;
_amount2 = getTokenBal(TokenInterface(token2));
}
amounts2[1] = _amount2;
}
approve(TokenInterface(token2), UAD3CRVf, _amount2);
lpAmount = IUbiquityMetaPool(UAD3CRVf).add_liquidity(amounts2, 0);
}
// STEP 3 : Farm/ApeIn : Deposit uAD3CRV-f LPs into UbiquityBondingV2 and get Ubiquity Bonding Shares
// UAD3CRVF
if (tok[5]) {
lpAmount = _amount;
}
address bonding = ubiquityManager.bondingContractAddress();
approve(TokenInterface(UAD3CRVf), bonding, lpAmount);
uint256 bondingShareId = IUbiquityBondingV2(bonding).deposit(
lpAmount,
durationWeeks
);
setUint(setId, bondingShareId);
_eventName = "LogDeposit(address,address,uint256,uint256,uint256,uint256,uint256,uint256)";
_eventParam = abi.encode(
address(this),
token,
amount,
bondingShareId,
lpAmount,
durationWeeks,
getId,
setId
);
}
/**
* @dev Withdraw from Ubiquity protocol
* @notice Ubiquity BondingShare => uAD3CRV-f => METAPOOL (3CRV / uAD) => 3POOL (DAI / USDC / USDT)
* @notice STEP 1 : Ubiquity BondingShare => uAD3CRV-f
* @notice STEP 2 : uAD3CRV-f => METAPOOL(3CRV / UAD)
* @notice STEP 3 : 3CRV => 3POOL (DAI / USDC / USDT)
* @param bondingShareId Bonding Share Id to withdraw
* @param token Token to withdraw to : DAI, USDC, USDT, 3CRV, uAD or uAD3CRV-f
* @param getId ID
* @param setId ID
*/
function withdraw(
uint256 bondingShareId,
address token,
uint256 getId,
uint256 setId
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
address UAD3CRVf = getUADCRV3();
bool[6] memory tok = [
token == DAI, // 0
token == USDC, // 1
token == USDT, // 2
token == CRV3, // 3
token == getUAD(), // 4
token == UAD3CRVf // 5
];
require(
// DAI / USDC / USDT / CRV3 / UAD / UAD3CRVF
tok[0] || tok[1] || tok[2] || tok[3] || tok[4] || tok[5],
"Invalid token: must be DAI, USDC, USDT, 3CRV, uAD or uAD3CRV-f"
);
uint256 _bondingShareId = getUint(getId, bondingShareId);
// Get Bond
IUbiquityBondingV2.Bond memory bond = IUbiquityBondingV2(
ubiquityManager.bondingShareAddress()
).getBond(_bondingShareId);
require(address(this) == bond.minter, "Not bond owner");
// STEP 1 : Withdraw Ubiquity Bonding Shares to get back uAD3CRV-f LPs
address bonding = ubiquityManager.bondingContractAddress();
IUbiquityBondingV2(bonding).removeLiquidity(
bond.lpAmount,
_bondingShareId
);
// STEP 2 : Withdraw uAD3CRV-f LPs to get back uAD or 3Crv
// DAI / USDC / USDT / CRV3 / UAD
if (tok[0] || tok[1] || tok[2] || tok[3] || tok[4]) {
uint256 amount2 = getTokenBal(TokenInterface(UAD3CRVf));
IUbiquityMetaPool(UAD3CRVf).remove_liquidity_one_coin(
amount2,
tok[4] ? 0 : 1,
0
);
}
// STEP 3 : Withdraw 3Crv LPs from 3Pool to get back DAI, USDC or USDT
// DAI / USDC / USDT
if (tok[0] || tok[1] || tok[2]) {
uint256 amount1 = getTokenBal(TokenInterface(CRV3));
I3Pool(Pool3).remove_liquidity_one_coin(
amount1,
tok[0] ? 0 : (tok[1] ? 1 : 2),
0
);
}
uint256 amount = getTokenBal(TokenInterface(token));
setUint(setId, amount);
_eventName = "LogWithdraw(address,uint256,uint256,uint256,address,uint256,uint256,uint256)";
_eventParam = abi.encode(
address(this),
_bondingShareId,
bond.lpAmount,
bond.endBlock,
token,
amount,
getId,
setId
);
}
}
contract ConnectV2Ubiquity is UbiquityResolver {
string public constant name = "Ubiquity-v1";
}