Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
YieldProxy
Compiler Version
v0.8.3+commit.8d00100c
Optimization Enabled:
Yes with 800 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.3;
import "./utils/CollectableDust.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "./UbiquityAlgorithmicDollarManager.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "./interfaces/IJar.sol";
import "./interfaces/IERC20Ubiquity.sol";
contract YieldProxy is ReentrancyGuard, CollectableDust, Pausable {
using SafeERC20 for ERC20;
using SafeERC20 for IERC20Ubiquity;
struct UserInfo {
uint256 amount; // token amount deposited by the user with same decimals as underlying token
uint256 shares; // pickle jar shares
uint256 uadAmount; // amount of uAD staked
uint256 ubqAmount; // amount of UBQ staked
uint256 fee; // deposit fee with same decimals as underlying token
uint256 ratio; // used to calculate yield
uint256 bonusYield; // used to calculate bonusYield on yield in uAR
}
ERC20 public token;
IJar public jar;
uint256 public constant BONUS_YIELD_MAX = 10000; // 1000 = 10% 100 = 1% 10 = 0.1% 1 = 0.01%
uint256 public bonusYield; // 5000 = 50% 100 = 1% 10 = 0.1% 1 = 0.01%
uint256 public constant FEES_MAX = 100000; // 1000 = 1% 100 = 0.1% 10 = 0.01% 1 = 0.001%
uint256 public constant UBQ_RATE_MAX = 10000e18; // 100000e18 Amount of UBQ to be stake to reduce the deposit fees by 100%
uint256 public fees; // 10000 = 10%, 1000 = 1% 100 = 0.1% 10= 0.01% 1=0.001%
// 100e18, if the ubqRate is 100 and UBQ_RATE_MAX=10000 then 100/10000 = 0.01
// 1UBQ gives you 0.01% of fee reduction so 10000 UBQ gives you 100%
uint256 public ubqRate;
uint256 public ubqMaxAmount; // UBQ amount to stake to have 100%
// struct to store deposit details
mapping(address => UserInfo) private _balances;
UbiquityAlgorithmicDollarManager public manager;
event Deposit(
address indexed _user,
uint256 _amount,
uint256 _shares,
uint256 _fee,
uint256 _ratio,
uint256 _uadAmount,
uint256 _ubqAmount,
uint256 _bonusYield
);
event WithdrawAll(
address indexed _user,
uint256 _amount,
uint256 _shares,
uint256 _fee,
uint256 _ratio,
uint256 _uadAmount,
uint256 _ubqAmount,
uint256 _bonusYield,
uint256 _uARYield
);
modifier onlyAdmin() {
require(
manager.hasRole(manager.DEFAULT_ADMIN_ROLE(), msg.sender),
"YieldProxy::!admin"
);
_;
}
constructor(
address _manager,
address _jar,
uint256 _fees,
uint256 _ubqRate,
uint256 _bonusYield
) CollectableDust() Pausable() {
manager = UbiquityAlgorithmicDollarManager(_manager);
fees = _fees; // 10000 = 10%
jar = IJar(_jar);
token = ERC20(jar.token());
// dont accept weird token
assert(token.decimals() < 19);
ubqRate = _ubqRate;
bonusYield = _bonusYield;
ubqMaxAmount = (100e18 * UBQ_RATE_MAX) / ubqRate;
}
/// @dev deposit tokens needed by the pickle jar to receive an extra yield in form of ubiquity debts
/// @param _amount of token required by the pickle jar
/// @param _ubqAmount amount of UBQ token that will be stake to decrease your deposit fee
/// @param _uadAmount amount of uAD token that will be stake to increase your bonusYield
/// @notice weeks act as a multiplier for the amount of bonding shares to be received
function deposit(
uint256 _amount,
uint256 _uadAmount,
uint256 _ubqAmount
) external nonReentrant returns (bool) {
require(_amount > 0, "YieldProxy::amount==0");
UserInfo storage dep = _balances[msg.sender];
require(dep.amount == 0, "YieldProxy::DepoExist");
uint256 curFee = 0;
// we have to take into account the number of decimals of the udnerlying token
uint256 upatedAmount = _amount;
if (token.decimals() < 18) {
upatedAmount = _amount * 10**(18 - token.decimals());
}
if (
_ubqAmount < ubqMaxAmount
) // calculate fee based on ubqAmount if it is not the max
{
// calculate discount
uint256 discountPercentage = (ubqRate * _ubqAmount) / UBQ_RATE_MAX; // we need to divide by 100e18 to get the percentage
// calculate regular fee
curFee = ((_amount * fees) / FEES_MAX);
// calculate the discount for this fee
uint256 discount = (curFee * discountPercentage) / 100e18;
// remaining fee
curFee = curFee - discount;
}
// if we don't provide enough UAD the bonusYield will be lowered
uint256 calculatedBonusYield = BONUS_YIELD_MAX;
uint256 maxUadAmount = upatedAmount / 2;
if (_uadAmount < maxUadAmount) {
// calculate the percentage of extra yield you are entitled to
uint256 percentage = ((_uadAmount + maxUadAmount) * 100e18) /
maxUadAmount; // 133e18
// increase the bonus yield with that percentage
calculatedBonusYield = (bonusYield * percentage) / 100e18;
// should not be possible to have a higher yield than the max yield
assert(calculatedBonusYield <= BONUS_YIELD_MAX);
}
dep.fee = curFee; // with 18 decimals
dep.amount = _amount;
dep.ratio = jar.getRatio();
dep.uadAmount = _uadAmount;
dep.ubqAmount = _ubqAmount;
dep.bonusYield = calculatedBonusYield;
// transfer all the tokens from the user
token.safeTransferFrom(msg.sender, address(this), _amount);
// invest in the pickle jar
uint256 curBalance = jar.balanceOf(address(this));
// allowing token to be deposited into the jar
token.safeIncreaseAllowance(address(jar), _amount);
/* uint256 allthis = ERC20(jar.token()).allowance(
address(this),
address(jar)
);
uint256 allsender = ERC20(jar.token()).allowance(
msg.sender,
address(jar)
); */
jar.deposit(_amount);
dep.shares = jar.balanceOf(address(this)) - curBalance;
/* allthis = ERC20(manager.dollarTokenAddress()).allowance(
msg.sender,
address(this)
); */
if (_uadAmount > 0) {
ERC20(manager.dollarTokenAddress()).safeTransferFrom(
msg.sender,
address(this),
_uadAmount
);
}
if (_ubqAmount > 0) {
ERC20(manager.governanceTokenAddress()).safeTransferFrom(
msg.sender,
address(this),
_ubqAmount
);
}
emit Deposit(
msg.sender,
dep.amount,
dep.shares,
dep.fee,
dep.ratio,
dep.uadAmount,
dep.ubqAmount,
dep.bonusYield
);
return true;
// emit event
}
/* function depositWithPermit(
uint256 _amount,
uint256 _deadline,
bool _approveMax,
uint8 _v,
bytes32 _r,
bytes32 _s
) external returns (bool) {
require(_amount > 0, "YieldProxy::amount==0");
UserInfo storage dep = _balances[msg.sender];
if (dep.amount > 0) {
//calculer le yield et l'ajouter au nouveau fee
}
dep.fee = _amount / fees;
dep.amount = _amount - dep.fee;
dep.ratio = jar.getRatio();
uint256 value = _approveMax ? uint256(-1) : _amount;
token.permit(msg.sender, address(this), value, _deadline, _v, _r, _s);
token.safeTransferFrom(msg.sender, address(this), _amount);
emit Deposit(msg.sender, dep.amount, dep.fee, dep.ratio);
return true;
} */
function withdrawAll() external nonReentrant returns (bool) {
UserInfo storage dep = _balances[msg.sender];
require(dep.amount > 0, "YieldProxy::amount==0");
uint256 upatedAmount = dep.amount;
uint256 upatedFee = dep.fee;
if (token.decimals() < 18) {
upatedAmount = dep.amount * 10**(18 - token.decimals());
upatedFee = dep.fee * 10**(18 - token.decimals());
}
// calculate the yield in uAR
uint256 amountWithYield = (upatedAmount * jar.getRatio()) / dep.ratio;
// calculate the yield in uAR by multiplying by the calculated bonus yield and adding the fee
uint256 extraYieldBonus = 0;
uint256 uARYield = 0;
// we need to have a positive yield
if (amountWithYield > upatedAmount) {
extraYieldBonus = (((amountWithYield - upatedAmount) *
dep.bonusYield) / BONUS_YIELD_MAX);
uARYield =
extraYieldBonus +
(amountWithYield - upatedAmount) +
upatedFee;
}
delete dep.bonusYield;
// we only give back the amount deposited minus the deposit fee
// indeed the deposit fee will be converted to uAR yield
uint256 amountToTransferBack = dep.amount - dep.fee;
delete dep.fee;
delete dep.amount;
delete dep.ratio;
// retrieve the amount from the jar
jar.withdraw(dep.shares);
delete dep.shares;
// we send back the deposited UAD
if (dep.uadAmount > 0) {
ERC20(manager.dollarTokenAddress()).transfer(
msg.sender,
dep.uadAmount
);
}
delete dep.uadAmount;
// we send back the deposited UBQ
if (dep.ubqAmount > 0) {
ERC20(manager.governanceTokenAddress()).transfer(
msg.sender,
dep.ubqAmount
);
}
delete dep.ubqAmount;
// we send back the deposited amount - deposit fee
token.transfer(msg.sender, amountToTransferBack);
// send the rest to the treasury
token.transfer(
manager.treasuryAddress(),
token.balanceOf(address(this))
);
// we send the yield as UAR
IERC20Ubiquity autoRedeemToken = IERC20Ubiquity(
manager.autoRedeemTokenAddress()
);
autoRedeemToken.mint(address(this), uARYield);
autoRedeemToken.transfer(msg.sender, uARYield);
// emit event
emit WithdrawAll(
msg.sender,
dep.amount,
dep.shares,
dep.fee,
dep.ratio,
dep.uadAmount,
dep.ubqAmount,
dep.bonusYield,
uARYield
);
return true;
}
/// Collectable Dust
function addProtocolToken(address _token) external override onlyAdmin {
_addProtocolToken(_token);
}
function removeProtocolToken(address _token) external override onlyAdmin {
_removeProtocolToken(_token);
}
function sendDust(
address _to,
address _token,
uint256 _amount
) external override onlyAdmin {
_sendDust(_to, _token, _amount);
}
function setDepositFees(uint256 _fees) external onlyAdmin {
require(_fees != fees, "YieldProxy::===fees");
fees = _fees;
}
function setUBQRate(uint256 _ubqRate) external onlyAdmin {
require(_ubqRate != ubqRate, "YieldProxy::===ubqRate");
require(_ubqRate <= UBQ_RATE_MAX, "YieldProxy::>ubqRateMAX");
ubqRate = _ubqRate;
ubqMaxAmount = 100 * (UBQ_RATE_MAX / ubqRate) * 1e18; // equivalent to 100 / (ubqRate/ UBQ_RATE_MAX)
}
/* function setMaxUAD(uint256 _maxUADPercent) external onlyAdmin {
require(_maxUADPercent != UADPercent, "YieldProxy::===maxUAD");
require(_maxUADPercent <= UADPercentMax, "YieldProxy::>UADPercentMax");
UADPercent = _maxUADPercent;
} */
function setJar(address _jar) external onlyAdmin {
require(_jar != address(0), "YieldProxy::!Jar");
jar = IJar(_jar);
token = ERC20(jar.token());
}
function getInfo(address _address)
external
view
returns (uint256[7] memory)
{
UserInfo memory dep = _balances[_address];
return [
dep.amount,
dep.shares,
dep.uadAmount,
dep.ubqAmount,
dep.fee,
dep.ratio,
dep.bonusYield
];
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "../interfaces/utils/ICollectableDust.sol";
abstract contract CollectableDust is ICollectableDust {
using SafeERC20 for IERC20;
using EnumerableSet for EnumerableSet.AddressSet;
address public constant ETH_ADDRESS =
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
EnumerableSet.AddressSet internal _protocolTokens;
// solhint-disable-next-line no-empty-blocks
constructor() {}
function _addProtocolToken(address _token) internal {
require(
!_protocolTokens.contains(_token),
"collectable-dust::token-is-part-of-the-protocol"
);
_protocolTokens.add(_token);
emit ProtocolTokenAdded(_token);
}
function _removeProtocolToken(address _token) internal {
require(
_protocolTokens.contains(_token),
"collectable-dust::token-not-part-of-the-protocol"
);
_protocolTokens.remove(_token);
emit ProtocolTokenRemoved(_token);
}
function _sendDust(
address _to,
address _token,
uint256 _amount
) internal {
require(
_to != address(0),
"collectable-dust::cant-send-dust-to-zero-address"
);
require(
!_protocolTokens.contains(_token),
"collectable-dust::token-is-part-of-the-protocol"
);
if (_token == ETH_ADDRESS) {
payable(_to).transfer(_amount);
} else {
IERC20(_token).safeTransfer(_to, _amount);
}
emit DustSent(_to, _token, _amount);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin guidelines: functions revert instead
* of returning `false` on failure. This behavior is nonetheless conventional
* and does not conflict with the expectations of ERC20 applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* The default value of {decimals} is 18. To select a different value for
* {decimals} you should overload it.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5,05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless this function is
* overridden;
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* Requirements:
*
* - `sender` and `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for ``sender``'s tokens of at least
* `amount`.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][_msgSender()];
require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
unchecked {
_approve(sender, _msgSender(), currentAllowance - amount);
}
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
uint256 currentAllowance = _allowances[_msgSender()][spender];
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(_msgSender(), spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `sender` to `recipient`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/
function _transfer(
address sender,
address recipient,
uint256 amount
) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[sender] = senderBalance - amount;
}
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
_afterTokenTransfer(sender, recipient, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
}
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
require(paused(), "Pausable: not paused");
_;
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./interfaces/IUbiquityAlgorithmicDollar.sol";
import "./interfaces/ICurveFactory.sol";
import "./interfaces/IMetaPool.sol";
import "./TWAPOracle.sol";
/// @title A central config for the uAD system. Also acts as a central
/// access control manager.
/// @notice For storing constants. For storing variables and allowing them to
/// be changed by the admin (governance)
/// @dev This should be used as a central access control manager which other
/// contracts use to check permissions
contract UbiquityAlgorithmicDollarManager is AccessControl {
using SafeERC20 for IERC20;
bytes32 public constant UBQ_MINTER_ROLE = keccak256("UBQ_MINTER_ROLE");
bytes32 public constant UBQ_BURNER_ROLE = keccak256("UBQ_BURNER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
bytes32 public constant COUPON_MANAGER_ROLE = keccak256("COUPON_MANAGER");
bytes32 public constant BONDING_MANAGER_ROLE = keccak256("BONDING_MANAGER");
bytes32 public constant INCENTIVE_MANAGER_ROLE =
keccak256("INCENTIVE_MANAGER");
bytes32 public constant UBQ_TOKEN_MANAGER_ROLE =
keccak256("UBQ_TOKEN_MANAGER_ROLE");
address public twapOracleAddress;
address public debtCouponAddress;
address public dollarTokenAddress; // uAD
address public couponCalculatorAddress;
address public dollarMintingCalculatorAddress;
address public bondingShareAddress;
address public bondingContractAddress;
address public stableSwapMetaPoolAddress;
address public curve3PoolTokenAddress; // 3CRV
address public treasuryAddress;
address public governanceTokenAddress; // uGOV
address public sushiSwapPoolAddress; // sushi pool uAD-uGOV
address public masterChefAddress;
address public formulasAddress;
address public autoRedeemTokenAddress; // uAR
address public uarCalculatorAddress; // uAR calculator
//key = address of couponmanager, value = excessdollardistributor
mapping(address => address) private _excessDollarDistributors;
modifier onlyAdmin() {
require(
hasRole(DEFAULT_ADMIN_ROLE, msg.sender),
"uADMGR: Caller is not admin"
);
_;
}
constructor(address _admin) {
_setupRole(DEFAULT_ADMIN_ROLE, _admin);
_setupRole(UBQ_MINTER_ROLE, _admin);
_setupRole(PAUSER_ROLE, _admin);
_setupRole(COUPON_MANAGER_ROLE, _admin);
_setupRole(BONDING_MANAGER_ROLE, _admin);
_setupRole(INCENTIVE_MANAGER_ROLE, _admin);
_setupRole(UBQ_TOKEN_MANAGER_ROLE, address(this));
}
// TODO Add a generic setter for extra addresses that needs to be linked
function setTwapOracleAddress(address _twapOracleAddress)
external
onlyAdmin
{
twapOracleAddress = _twapOracleAddress;
// to be removed
TWAPOracle oracle = TWAPOracle(twapOracleAddress);
oracle.update();
}
function setuARTokenAddress(address _uarTokenAddress) external onlyAdmin {
autoRedeemTokenAddress = _uarTokenAddress;
}
function setDebtCouponAddress(address _debtCouponAddress)
external
onlyAdmin
{
debtCouponAddress = _debtCouponAddress;
}
function setIncentiveToUAD(address _account, address _incentiveAddress)
external
onlyAdmin
{
IUbiquityAlgorithmicDollar(dollarTokenAddress).setIncentiveContract(
_account,
_incentiveAddress
);
}
function setDollarTokenAddress(address _dollarTokenAddress)
external
onlyAdmin
{
dollarTokenAddress = _dollarTokenAddress;
}
function setGovernanceTokenAddress(address _governanceTokenAddress)
external
onlyAdmin
{
governanceTokenAddress = _governanceTokenAddress;
}
function setSushiSwapPoolAddress(address _sushiSwapPoolAddress)
external
onlyAdmin
{
sushiSwapPoolAddress = _sushiSwapPoolAddress;
}
function setUARCalculatorAddress(address _uarCalculatorAddress)
external
onlyAdmin
{
uarCalculatorAddress = _uarCalculatorAddress;
}
function setCouponCalculatorAddress(address _couponCalculatorAddress)
external
onlyAdmin
{
couponCalculatorAddress = _couponCalculatorAddress;
}
function setDollarMintingCalculatorAddress(
address _dollarMintingCalculatorAddress
) external onlyAdmin {
dollarMintingCalculatorAddress = _dollarMintingCalculatorAddress;
}
function setExcessDollarsDistributor(
address debtCouponManagerAddress,
address excessCouponDistributor
) external onlyAdmin {
_excessDollarDistributors[
debtCouponManagerAddress
] = excessCouponDistributor;
}
function setMasterChefAddress(address _masterChefAddress)
external
onlyAdmin
{
masterChefAddress = _masterChefAddress;
}
function setFormulasAddress(address _formulasAddress) external onlyAdmin {
formulasAddress = _formulasAddress;
}
function setBondingShareAddress(address _bondingShareAddress)
external
onlyAdmin
{
bondingShareAddress = _bondingShareAddress;
}
function setStableSwapMetaPoolAddress(address _stableSwapMetaPoolAddress)
external
onlyAdmin
{
stableSwapMetaPoolAddress = _stableSwapMetaPoolAddress;
}
/**
@notice set the bonding bontract smart contract address
@dev bonding contract participants deposit curve LP token
for a certain duration to earn uGOV and more curve LP token
@param _bondingContractAddress bonding contract address
*/
function setBondingContractAddress(address _bondingContractAddress)
external
onlyAdmin
{
bondingContractAddress = _bondingContractAddress;
}
/**
@notice set the treasury address
@dev the treasury fund is used to maintain the protocol
@param _treasuryAddress treasury fund address
*/
function setTreasuryAddress(address _treasuryAddress) external onlyAdmin {
treasuryAddress = _treasuryAddress;
}
/**
@notice deploy a new Curve metapools for uAD Token uAD/3Pool
@dev From the curve documentation for uncollateralized algorithmic
stablecoins amplification should be 5-10
@param _curveFactory MetaPool factory address
@param _crvBasePool Address of the base pool to use within the new metapool.
@param _crv3PoolTokenAddress curve 3Pool token Address
@param _amplificationCoefficient amplification coefficient. The smaller
it is the closer to a constant product we are.
@param _fee Trade fee, given as an integer with 1e10 precision.
*/
function deployStableSwapPool(
address _curveFactory,
address _crvBasePool,
address _crv3PoolTokenAddress,
uint256 _amplificationCoefficient,
uint256 _fee
) external onlyAdmin {
// Create new StableSwap meta pool (uAD <-> 3Crv)
address metaPool = ICurveFactory(_curveFactory).deploy_metapool(
_crvBasePool,
ERC20(dollarTokenAddress).name(),
ERC20(dollarTokenAddress).symbol(),
dollarTokenAddress,
_amplificationCoefficient,
_fee
);
stableSwapMetaPoolAddress = metaPool;
// Approve the newly-deployed meta pool to transfer this contract's funds
uint256 crv3PoolTokenAmount = IERC20(_crv3PoolTokenAddress).balanceOf(
address(this)
);
uint256 uADTokenAmount = IERC20(dollarTokenAddress).balanceOf(
address(this)
);
// safe approve revert if approve from non-zero to non-zero allowance
IERC20(_crv3PoolTokenAddress).safeApprove(metaPool, 0);
IERC20(_crv3PoolTokenAddress).safeApprove(
metaPool,
crv3PoolTokenAmount
);
IERC20(dollarTokenAddress).safeApprove(metaPool, 0);
IERC20(dollarTokenAddress).safeApprove(metaPool, uADTokenAmount);
// coin at index 0 is uAD and index 1 is 3CRV
require(
IMetaPool(metaPool).coins(0) == dollarTokenAddress &&
IMetaPool(metaPool).coins(1) == _crv3PoolTokenAddress,
"uADMGR: COIN_ORDER_MISMATCH"
);
// Add the initial liquidity to the StableSwap meta pool
uint256[2] memory amounts = [
IERC20(dollarTokenAddress).balanceOf(address(this)),
IERC20(_crv3PoolTokenAddress).balanceOf(address(this))
];
// set curve 3Pool address
curve3PoolTokenAddress = _crv3PoolTokenAddress;
IMetaPool(metaPool).add_liquidity(amounts, 0, msg.sender);
}
function getExcessDollarsDistributor(address _debtCouponManagerAddress)
external
view
returns (address)
{
return _excessDollarDistributors[_debtCouponManagerAddress];
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IJar is IERC20 {
function claimInsurance() external; // NOTE: Only yDelegatedVault implements this
function depositAll() external;
function deposit(uint256) external;
function withdrawAll() external;
function withdraw(uint256) external;
function earn() external;
function token() external view returns (address);
function reward() external view returns (address);
function getRatio() external view returns (uint256);
function balance() external view returns (uint256);
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.3;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/// @title ERC20 Ubiquiti preset interface
/// @author Ubiquity Algorithmic Dollar
interface IERC20Ubiquity is IERC20 {
// ----------- Events -----------
event Minting(
address indexed _to,
address indexed _minter,
uint256 _amount
);
event Burning(address indexed _burned, uint256 _amount);
// ----------- State changing api -----------
function burn(uint256 amount) external;
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
// ----------- Burner only state changing api -----------
function burnFrom(address account, uint256 amount) external;
// ----------- Minter only state changing api -----------
function mint(address account, uint256 amount) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) private pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping(bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;
interface ICollectableDust {
event DustSent(address _to, address token, uint256 amount);
event ProtocolTokenAdded(address _token);
event ProtocolTokenRemoved(address _token);
function addProtocolToken(address _token) external;
function removeProtocolToken(address _token) external;
function sendDust(
address _to,
address _token,
uint256 _amount
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";
/**
* @dev External interface of AccessControl declared to support ERC165 detection.
*/
interface IAccessControl {
function hasRole(bytes32 role, address account) external view returns (bool);
function getRoleAdmin(bytes32 role) external view returns (bytes32);
function grantRole(bytes32 role, address account) external;
function revokeRole(bytes32 role, address account) external;
function renounceRole(bytes32 role, address account) external;
}
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*
* _Available since v3.1._
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {_setupRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with a standardized message including the required role.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{20}) is missing role (0x[0-9a-f]{32})$/
*
* _Available since v4.1._
*/
modifier onlyRole(bytes32 role) {
_checkRole(role, _msgSender());
_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view override returns (bool) {
return _roles[role].members[account];
}
/**
* @dev Revert with a standard message if `account` is missing `role`.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{20}) is missing role (0x[0-9a-f]{32})$/
*/
function _checkRole(bytes32 role, address account) internal view {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(uint160(account), 20),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event. Note that unlike {grantRole}, this function doesn't perform any
* checks on the calling account.
*
* [WARNING]
* ====
* This function should only be called from the constructor when setting
* up the initial roles for the system.
*
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*/
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
emit RoleAdminChanged(role, getRoleAdmin(role), adminRole);
_roles[role].adminRole = adminRole;
}
function _grantRole(bytes32 role, address account) private {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) private {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.3;
import "./IERC20Ubiquity.sol";
/// @title UAD stablecoin interface
/// @author Ubiquity Algorithmic Dollar
interface IUbiquityAlgorithmicDollar is IERC20Ubiquity {
event IncentiveContractUpdate(
address indexed _incentivized,
address indexed _incentiveContract
);
function setIncentiveContract(address account, address incentive) external;
function incentiveContract(address account) external view returns (address);
}// SPDX-License-Identifier: MIT
// !! THIS FILE WAS AUTOGENERATED BY abi-to-sol. SEE BELOW FOR SOURCE. !!
pragma solidity ^0.8.3;
interface ICurveFactory {
event BasePoolAdded(address base_pool, address implementat);
event MetaPoolDeployed(
address coin,
address base_pool,
uint256 A,
uint256 fee,
address deployer
);
function find_pool_for_coins(address _from, address _to)
external
view
returns (address);
function find_pool_for_coins(
address _from,
address _to,
uint256 i
) external view returns (address);
function get_n_coins(address _pool)
external
view
returns (uint256, uint256);
function get_coins(address _pool) external view returns (address[2] memory);
function get_underlying_coins(address _pool)
external
view
returns (address[8] memory);
function get_decimals(address _pool)
external
view
returns (uint256[2] memory);
function get_underlying_decimals(address _pool)
external
view
returns (uint256[8] memory);
function get_rates(address _pool) external view returns (uint256[2] memory);
function get_balances(address _pool)
external
view
returns (uint256[2] memory);
function get_underlying_balances(address _pool)
external
view
returns (uint256[8] memory);
function get_A(address _pool) external view returns (uint256);
function get_fees(address _pool) external view returns (uint256, uint256);
function get_admin_balances(address _pool)
external
view
returns (uint256[2] memory);
function get_coin_indices(
address _pool,
address _from,
address _to
)
external
view
returns (
int128,
int128,
bool
);
function add_base_pool(
address _base_pool,
address _metapool_implementation,
address _fee_receiver
) external;
function deploy_metapool(
address _base_pool,
string memory _name,
string memory _symbol,
address _coin,
uint256 _A,
uint256 _fee
) external returns (address);
function commit_transfer_ownership(address addr) external;
function accept_transfer_ownership() external;
function set_fee_receiver(address _base_pool, address _fee_receiver)
external;
function convert_fees() external returns (bool);
function admin() external view returns (address);
function future_admin() external view returns (address);
function pool_list(uint256 arg0) external view returns (address);
function pool_count() external view returns (uint256);
function base_pool_list(uint256 arg0) external view returns (address);
function base_pool_count() external view returns (uint256);
function fee_receiver(address arg0) external view returns (address);
}// SPDX-License-Identifier: UNLICENSED
// !! THIS FILE WAS AUTOGENERATED BY abi-to-sol. SEE BELOW FOR SOURCE. !!
pragma solidity ^0.8.3;
interface IMetaPool {
event Transfer(
address indexed sender,
address indexed receiver,
uint256 value
);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
event TokenExchange(
address indexed buyer,
int128 sold_id,
uint256 tokens_sold,
int128 bought_id,
uint256 tokens_bought
);
event TokenExchangeUnderlying(
address indexed buyer,
int128 sold_id,
uint256 tokens_sold,
int128 bought_id,
uint256 tokens_bought
);
event AddLiquidity(
address indexed provider,
uint256[2] token_amounts,
uint256[2] fees,
uint256 invariant,
uint256 token_supply
);
event RemoveLiquidity(
address indexed provider,
uint256[2] token_amounts,
uint256[2] fees,
uint256 token_supply
);
event RemoveLiquidityOne(
address indexed provider,
uint256 token_amount,
uint256 coin_amount,
uint256 token_supply
);
event RemoveLiquidityImbalance(
address indexed provider,
uint256[2] token_amounts,
uint256[2] fees,
uint256 invariant,
uint256 token_supply
);
event CommitNewAdmin(uint256 indexed deadline, address indexed admin);
event NewAdmin(address indexed admin);
event CommitNewFee(
uint256 indexed deadline,
uint256 fee,
uint256 admin_fee
);
event NewFee(uint256 fee, uint256 admin_fee);
event RampA(
uint256 old_A,
uint256 new_A,
uint256 initial_time,
uint256 future_time
);
event StopRampA(uint256 A, uint256 t);
function initialize(
string memory _name,
string memory _symbol,
address _coin,
uint256 _decimals,
uint256 _A,
uint256 _fee,
address _admin
) external;
function decimals() external view returns (uint256);
function transfer(address _to, uint256 _value) external returns (bool);
function transferFrom(
address _from,
address _to,
uint256 _value
) external returns (bool);
function approve(address _spender, uint256 _value) external returns (bool);
function get_previous_balances() external view returns (uint256[2] memory);
function get_balances() external view returns (uint256[2] memory);
function get_twap_balances(
uint256[2] memory _first_balances,
uint256[2] memory _last_balances,
uint256 _time_elapsed
) external view returns (uint256[2] memory);
function get_price_cumulative_last()
external
view
returns (uint256[2] memory);
function admin_fee() external view returns (uint256);
function A() external view returns (uint256);
function A_precise() external view returns (uint256);
function get_virtual_price() external view returns (uint256);
function calc_token_amount(uint256[2] memory _amounts, bool _is_deposit)
external
view
returns (uint256);
function calc_token_amount(
uint256[2] memory _amounts,
bool _is_deposit,
bool _previous
) external view returns (uint256);
function add_liquidity(uint256[2] memory _amounts, uint256 _min_mint_amount)
external
returns (uint256);
function add_liquidity(
uint256[2] memory _amounts,
uint256 _min_mint_amount,
address _receiver
) external returns (uint256);
function get_dy(
int128 i,
int128 j,
uint256 dx
) external view returns (uint256);
function get_dy(
int128 i,
int128 j,
uint256 dx,
uint256[2] memory _balances
) external view returns (uint256);
function get_dy_underlying(
int128 i,
int128 j,
uint256 dx
) external view returns (uint256);
function get_dy_underlying(
int128 i,
int128 j,
uint256 dx,
uint256[2] memory _balances
) external view returns (uint256);
function exchange(
int128 i,
int128 j,
uint256 dx,
uint256 min_dy
) external returns (uint256);
function exchange(
int128 i,
int128 j,
uint256 dx,
uint256 min_dy,
address _receiver
) external returns (uint256);
function exchange_underlying(
int128 i,
int128 j,
uint256 dx,
uint256 min_dy
) external returns (uint256);
function exchange_underlying(
int128 i,
int128 j,
uint256 dx,
uint256 min_dy,
address _receiver
) external returns (uint256);
function remove_liquidity(
uint256 _burn_amount,
uint256[2] memory _min_amounts
) external returns (uint256[2] memory);
function remove_liquidity(
uint256 _burn_amount,
uint256[2] memory _min_amounts,
address _receiver
) external returns (uint256[2] memory);
function remove_liquidity_imbalance(
uint256[2] memory _amounts,
uint256 _max_burn_amount
) external returns (uint256);
function remove_liquidity_imbalance(
uint256[2] memory _amounts,
uint256 _max_burn_amount,
address _receiver
) external returns (uint256);
function calc_withdraw_one_coin(uint256 _burn_amount, int128 i)
external
view
returns (uint256);
function calc_withdraw_one_coin(
uint256 _burn_amount,
int128 i,
bool _previous
) external view returns (uint256);
function remove_liquidity_one_coin(
uint256 _burn_amount,
int128 i,
uint256 _min_received
) external returns (uint256);
function remove_liquidity_one_coin(
uint256 _burn_amount,
int128 i,
uint256 _min_received,
address _receiver
) external returns (uint256);
function ramp_A(uint256 _future_A, uint256 _future_time) external;
function stop_ramp_A() external;
function admin_balances(uint256 i) external view returns (uint256);
function withdraw_admin_fees() external;
function admin() external view returns (address);
function coins(uint256 arg0) external view returns (address);
function balances(uint256 arg0) external view returns (uint256);
function fee() external view returns (uint256);
function block_timestamp_last() external view returns (uint256);
function initial_A() external view returns (uint256);
function future_A() external view returns (uint256);
function initial_A_time() external view returns (uint256);
function future_A_time() external view returns (uint256);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function balanceOf(address arg0) external view returns (uint256);
function allowance(address arg0, address arg1)
external
view
returns (uint256);
function totalSupply() external view returns (uint256);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.3;
import "./interfaces/IMetaPool.sol";
contract TWAPOracle {
address public immutable pool;
address public immutable token0;
address public immutable token1;
uint256 public price0Average;
uint256 public price1Average;
uint256 public pricesBlockTimestampLast;
uint256[2] public priceCumulativeLast;
constructor(
address _pool,
address _uADtoken0,
address _curve3CRVtoken1
) {
pool = _pool;
// coin at index 0 is uAD and index 1 is 3CRV
require(
IMetaPool(_pool).coins(0) == _uADtoken0 &&
IMetaPool(_pool).coins(1) == _curve3CRVtoken1,
"TWAPOracle: COIN_ORDER_MISMATCH"
);
token0 = _uADtoken0;
token1 = _curve3CRVtoken1;
uint256 _reserve0 = uint112(IMetaPool(_pool).balances(0));
uint256 _reserve1 = uint112(IMetaPool(_pool).balances(1));
// ensure that there's liquidity in the pair
require(_reserve0 != 0 && _reserve1 != 0, "TWAPOracle: NO_RESERVES");
// ensure that pair balance is perfect
require(_reserve0 == _reserve1, "TWAPOracle: PAIR_UNBALANCED");
priceCumulativeLast = IMetaPool(_pool).get_price_cumulative_last();
pricesBlockTimestampLast = IMetaPool(_pool).block_timestamp_last();
price0Average = 1 ether;
price1Average = 1 ether;
}
// calculate average price
function update() external {
(
uint256[2] memory priceCumulative,
uint256 blockTimestamp
) = _currentCumulativePrices();
if (blockTimestamp - pricesBlockTimestampLast > 0) {
// get the balances between now and the last price cumulative snapshot
uint256[2] memory twapBalances = IMetaPool(pool).get_twap_balances(
priceCumulativeLast,
priceCumulative,
blockTimestamp - pricesBlockTimestampLast
);
// price to exchange amounIn uAD to 3CRV based on TWAP
price0Average = IMetaPool(pool).get_dy(0, 1, 1 ether, twapBalances);
// price to exchange amounIn 3CRV to uAD based on TWAP
price1Average = IMetaPool(pool).get_dy(1, 0, 1 ether, twapBalances);
// we update the priceCumulative
priceCumulativeLast = priceCumulative;
pricesBlockTimestampLast = blockTimestamp;
}
}
// note this will always return 0 before update has been called successfully
// for the first time.
function consult(address token) external view returns (uint256 amountOut) {
if (token == token0) {
// price to exchange 1 uAD to 3CRV based on TWAP
amountOut = price0Average;
} else {
require(token == token1, "TWAPOracle: INVALID_TOKEN");
// price to exchange 1 3CRV to uAD based on TWAP
amountOut = price1Average;
}
}
function _currentCumulativePrices()
internal
view
returns (uint256[2] memory priceCumulative, uint256 blockTimestamp)
{
priceCumulative = IMetaPool(pool).get_price_cumulative_last();
blockTimestamp = IMetaPool(pool).block_timestamp_last();
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"optimizer": {
"enabled": true,
"runs": 800
},
"metadata": {
"bytecodeHash": "none",
"useLiteralContent": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_manager","type":"address"},{"internalType":"address","name":"_jar","type":"address"},{"internalType":"uint256","name":"_fees","type":"uint256"},{"internalType":"uint256","name":"_ubqRate","type":"uint256"},{"internalType":"uint256","name":"_bonusYield","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_ratio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_uadAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_ubqAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_bonusYield","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DustSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"}],"name":"ProtocolTokenAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"}],"name":"ProtocolTokenRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_ratio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_uadAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_ubqAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_bonusYield","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_uARYield","type":"uint256"}],"name":"WithdrawAll","type":"event"},{"inputs":[],"name":"BONUS_YIELD_MAX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEES_MAX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UBQ_RATE_MAX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"addProtocolToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bonusYield","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_uadAmount","type":"uint256"},{"internalType":"uint256","name":"_ubqAmount","type":"uint256"}],"name":"deposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getInfo","outputs":[{"internalType":"uint256[7]","name":"","type":"uint256[7]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"jar","outputs":[{"internalType":"contract IJar","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"contract UbiquityAlgorithmicDollarManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"removeProtocolToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"sendDust","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fees","type":"uint256"}],"name":"setDepositFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_jar","type":"address"}],"name":"setJar","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_ubqRate","type":"uint256"}],"name":"setUBQRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ubqMaxAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ubqRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b5060405162002f2438038062002f2483398101604081905262000034916200023c565b60016000556003805460ff19169055600a80546001600160a01b038088166001600160a01b031992831617909255600685905560048054928716929091168217815560408051637e062a3560e11b8152905163fc0c546a92828101926020929190829003018186803b158015620000aa57600080fd5b505afa158015620000bf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000e5919062000218565b600360016101000a8154816001600160a01b0302191690836001600160a01b031602179055506013600360019054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156200015c57600080fd5b505afa15801562000171573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200019791906200028e565b60ff1610620001b657634e487b7160e01b600052600160045260246000fd5b6007829055600581905581620001e069021e19e0c9bab240000068056bc75e2d63100000620002d2565b620001ec9190620002b1565b60085550620002fe9350505050565b80516001600160a01b03811681146200021357600080fd5b919050565b6000602082840312156200022a578081fd5b6200023582620001fb565b9392505050565b600080600080600060a0868803121562000254578081fd5b6200025f86620001fb565b94506200026f60208701620001fb565b6040870151606088015160809098015196999198509695945092505050565b600060208284031215620002a0578081fd5b815160ff8116811462000235578182fd5b600082620002cd57634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615620002f957634e487b7160e01b81526011600452602481fd5b500290565b612c16806200030e6000396000f3fe608060405234801561001057600080fd5b50600436106101765760003560e01c8063a734f06e116100d8578063e34bad3f1161008c578063fa3305c911610066578063fa3305c9146102c6578063fc0c546a146102d9578063ffdd5cf1146102f157610176565b8063e34bad3f146102a1578063f159e287146102aa578063f6f482aa146102b357610176565b8063be38a4fe116100bd578063be38a4fe14610268578063bf0d68e41461027b578063c4de21ff1461028e57610176565b8063a734f06e1461023c578063ada5b0df1461025757610176565b8063572af87d1161012f5780637e9bcdf5116101145780637e9bcdf514610222578063853828b61461022b5780639af1d35a1461023357610176565b8063572af87d1461020d5780635c975abb1461021757610176565b80632db8c129116101605780632db8c129146101b8578063481c6a75146101cb5780634d72b0a7146101f657610176565b8062aeef8a1461017b578063278188d6146101a3575b600080fd5b61018e61018936600461293e565b610311565b60405190151581526020015b60405180910390f35b6101b66101b1366004612926565b610a3e565b005b6101b66101c63660046128ae565b610c61565b600a546101de906001600160a01b031681565b6040516001600160a01b03909116815260200161019a565b6101ff60075481565b60405190815260200161019a565b6101ff620186a081565b60035460ff1661018e565b6101ff60055481565b61018e610dac565b6101ff60065481565b6101de73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b6101ff69021e19e0c9bab240000081565b6004546101de906001600160a01b031681565b6101b6610289366004612876565b61182e565b6101b661029c366004612926565b611975565b6101ff60085481565b6101ff61271081565b6101b66102c1366004612876565b611b07565b6101b66102d4366004612876565b611d62565b6003546101de9061010090046001600160a01b031681565b6103046102ff366004612876565b611ea6565b60405161019a91906129a6565b60006002600054141561036b5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b6002600055836103bd5760405162461bcd60e51b815260206004820152601560248201527f5969656c6450726f78793a3a616d6f756e743d3d3000000000000000000000006044820152606401610362565b33600090815260096020526040902080541561041b5760405162461bcd60e51b815260206004820152601560248201527f5969656c6450726f78793a3a4465706f457869737400000000000000000000006044820152606401610362565b6000808690506012600360019054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561047157600080fd5b505afa158015610485573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a99190612969565b60ff16101561055b57600360019054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561050057600080fd5b505afa158015610514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105389190612969565b610543906012612b8f565b61054e90600a612a88565b6105589088612b59565b90505b6008548510156105db57600069021e19e0c9bab2400000866007546105809190612b59565b61058a9190612a22565b9050620186a06006548961059e9190612b59565b6105a89190612a22565b9250600068056bc75e2d631000006105c08386612b59565b6105ca9190612a22565b90506105d68185612b78565b935050505b61271060006105eb600284612a22565b90508088101561066757600081610602818b612a0a565b6106159068056bc75e2d63100000612b59565b61061f9190612a22565b905068056bc75e2d63100000816005546106399190612b59565b6106439190612a22565b925061271083111561066557634e487b7160e01b600052600160045260246000fd5b505b600480860185905589865580546040805163760f5ebd60e11b815290516001600160a01b039092169263ec1ebd7a928282019260209290829003018186803b1580156106b257600080fd5b505afa1580156106c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ea919061290e565b600586015560028501889055600380860188905560068601839055546107209061010090046001600160a01b031633308c611f7f565b600480546040516370a0823160e01b815230928101929092526000916001600160a01b03909116906370a082319060240160206040518083038186803b15801561076957600080fd5b505afa15801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a1919061290e565b6004546003549192506107c69161010090046001600160a01b0390811691168c612005565b6004805460405163b6b55f2560e01b81529182018c90526001600160a01b03169063b6b55f2590602401600060405180830381600087803b15801561080a57600080fd5b505af115801561081e573d6000803e3d6000fd5b5050600480546040516370a0823160e01b815230928101929092528493506001600160a01b031691506370a082319060240160206040518083038186803b15801561086857600080fd5b505afa15801561087c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a0919061290e565b6108aa9190612b78565b600187015588156109525761095233308b600a60009054906101000a90046001600160a01b03166001600160a01b031663bc3ea0186040518163ffffffff1660e01b815260040160206040518083038186803b15801561090957600080fd5b505afa15801561091d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109419190612892565b6001600160a01b0316929190611f7f565b87156109ac576109ac33308a600a60009054906101000a90046001600160a01b03166001600160a01b031663b42165d06040518163ffffffff1660e01b815260040160206040518083038186803b15801561090957600080fd5b855460018701546004880154600589015460028a015460038b015460068c0154604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015233907f65b7b85cb51750af94dfd9985b1f2ab59acaeaf63a242f2415e0b4c84b657ee09060e00160405180910390a26001965050505050505060016000559392505050565b600a546040805163a217fddf60e01b815290516001600160a01b03909216916391d1485491839163a217fddf91600480820192602092909190829003018186803b158015610a8b57600080fd5b505afa158015610a9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac3919061290e565b6040516001600160e01b031960e084901b168152600481019190915233602482015260440160206040518083038186803b158015610b0057600080fd5b505afa158015610b14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3891906128ee565b610b795760405162461bcd60e51b81526020600482015260126024820152712cb4b2b632283937bc3c9d1d10b0b236b4b760711b6044820152606401610362565b600754811415610bcb5760405162461bcd60e51b815260206004820152601660248201527f5969656c6450726f78793a3a3d3d3d75627152617465000000000000000000006044820152606401610362565b69021e19e0c9bab2400000811115610c255760405162461bcd60e51b815260206004820152601760248201527f5969656c6450726f78793a3a3e756271526174654d41580000000000000000006044820152606401610362565b6007819055610c3e8169021e19e0c9bab2400000612a22565b610c49906064612b59565b610c5b90670de0b6b3a7640000612b59565b60085550565b600a546040805163a217fddf60e01b815290516001600160a01b03909216916391d1485491839163a217fddf91600480820192602092909190829003018186803b158015610cae57600080fd5b505afa158015610cc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce6919061290e565b6040516001600160e01b031960e084901b168152600481019190915233602482015260440160206040518083038186803b158015610d2357600080fd5b505afa158015610d37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5b91906128ee565b610d9c5760405162461bcd60e51b81526020600482015260126024820152712cb4b2b632283937bc3c9d1d10b0b236b4b760711b6044820152606401610362565b610da78383836120c6565b505050565b600060026000541415610e015760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610362565b600260009081553381526009602052604090208054610e625760405162461bcd60e51b815260206004820152601560248201527f5969656c6450726f78793a3a616d6f756e743d3d3000000000000000000000006044820152606401610362565b80546004808301546003546040805163313ce56760e01b8152905192936012936101009093046001600160a01b03169263313ce567928083019260209291829003018186803b158015610eb457600080fd5b505afa158015610ec8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eec9190612969565b60ff16101561104d57600360019054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610f4357600080fd5b505afa158015610f57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7b9190612969565b610f86906012612b8f565b610f9190600a612a88565b8354610f9d9190612b59565b9150600360019054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610fed57600080fd5b505afa158015611001573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110259190612969565b611030906012612b8f565b61103b90600a612a88565b836004015461104a9190612b59565b90505b60008360050154600460009054906101000a90046001600160a01b03166001600160a01b031663ec1ebd7a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110a257600080fd5b505afa1580156110b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110da919061290e565b6110e49085612b59565b6110ee9190612a22565b9050600080848311156111465760068601546127109061110e8786612b78565b6111189190612b59565b6111229190612a22565b91508361112f8685612b78565b6111399084612a0a565b6111439190612a0a565b90505b600060068701819055600487015487546111609190612b78565b60006004898101829055818a5560058a0191909155805460018a0154604051632e1a7d4d60e01b8152928301529192506001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b1580156111bf57600080fd5b505af11580156111d3573d6000803e3d6000fd5b5050600060018a015550506002870154156112f857600a60009054906101000a90046001600160a01b03166001600160a01b031663bc3ea0186040518163ffffffff1660e01b815260040160206040518083038186803b15801561123657600080fd5b505afa15801561124a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126e9190612892565b600288015460405163a9059cbb60e01b815233600482015260248101919091526001600160a01b03919091169063a9059cbb90604401602060405180830381600087803b1580156112be57600080fd5b505af11580156112d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f691906128ee565b505b6000600288015560038701541561141957600a60009054906101000a90046001600160a01b03166001600160a01b031663b42165d06040518163ffffffff1660e01b815260040160206040518083038186803b15801561135757600080fd5b505afa15801561136b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138f9190612892565b600388015460405163a9059cbb60e01b815233600482015260248101919091526001600160a01b03919091169063a9059cbb90604401602060405180830381600087803b1580156113df57600080fd5b505af11580156113f3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141791906128ee565b505b60006003888101919091555460405163a9059cbb60e01b8152336004820152602481018390526101009091046001600160a01b03169063a9059cbb90604401602060405180830381600087803b15801561147257600080fd5b505af1158015611486573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114aa91906128ee565b50600354600a546040805163c5f956af60e01b815290516001600160a01b0361010090940484169363a9059cbb93169163c5f956af916004808301926020929190829003018186803b1580156114ff57600080fd5b505afa158015611513573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115379190612892565b6003546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a082319060240160206040518083038186803b15801561157e57600080fd5b505afa158015611592573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b6919061290e565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b1580156115fc57600080fd5b505af1158015611610573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163491906128ee565b50600a5460408051630eb8f66960e21b815290516000926001600160a01b031691633ae3d9a4916004808301926020929190829003018186803b15801561167a57600080fd5b505afa15801561168e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116b29190612892565b6040516340c10f1960e01b8152306004820152602481018590529091506001600160a01b038216906340c10f1990604401600060405180830381600087803b1580156116fd57600080fd5b505af1158015611711573d6000803e3d6000fd5b505060405163a9059cbb60e01b8152336004820152602481018690526001600160a01b038416925063a9059cbb9150604401602060405180830381600087803b15801561175d57600080fd5b505af1158015611771573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061179591906128ee565b508754600189015460048a015460058b015460028c015460038d015460068e0154604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0810184905233907ff7cb8fce12fe949c9a4a6407e6d597806d10fc3b98b10b0d2de66b58e6e76cef906101000160405180910390a2600198505050505050505050600160005590565b600a546040805163a217fddf60e01b815290516001600160a01b03909216916391d1485491839163a217fddf91600480820192602092909190829003018186803b15801561187b57600080fd5b505afa15801561188f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b3919061290e565b6040516001600160e01b031960e084901b168152600481019190915233602482015260440160206040518083038186803b1580156118f057600080fd5b505afa158015611904573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192891906128ee565b6119695760405162461bcd60e51b81526020600482015260126024820152712cb4b2b632283937bc3c9d1d10b0b236b4b760711b6044820152606401610362565b61197281612277565b50565b600a546040805163a217fddf60e01b815290516001600160a01b03909216916391d1485491839163a217fddf91600480820192602092909190829003018186803b1580156119c257600080fd5b505afa1580156119d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119fa919061290e565b6040516001600160e01b031960e084901b168152600481019190915233602482015260440160206040518083038186803b158015611a3757600080fd5b505afa158015611a4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6f91906128ee565b611ab05760405162461bcd60e51b81526020600482015260126024820152712cb4b2b632283937bc3c9d1d10b0b236b4b760711b6044820152606401610362565b600654811415611b025760405162461bcd60e51b815260206004820152601360248201527f5969656c6450726f78793a3a3d3d3d66656573000000000000000000000000006044820152606401610362565b600655565b600a546040805163a217fddf60e01b815290516001600160a01b03909216916391d1485491839163a217fddf91600480820192602092909190829003018186803b158015611b5457600080fd5b505afa158015611b68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8c919061290e565b6040516001600160e01b031960e084901b168152600481019190915233602482015260440160206040518083038186803b158015611bc957600080fd5b505afa158015611bdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0191906128ee565b611c425760405162461bcd60e51b81526020600482015260126024820152712cb4b2b632283937bc3c9d1d10b0b236b4b760711b6044820152606401610362565b6001600160a01b038116611c985760405162461bcd60e51b815260206004820152601060248201527f5969656c6450726f78793a3a214a6172000000000000000000000000000000006044820152606401610362565b600480547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038316908117825560408051637e062a3560e11b81529051919263fc0c546a928282019260209290829003018186803b158015611d0157600080fd5b505afa158015611d15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d399190612892565b600360016101000a8154816001600160a01b0302191690836001600160a01b0316021790555050565b600a546040805163a217fddf60e01b815290516001600160a01b03909216916391d1485491839163a217fddf91600480820192602092909190829003018186803b158015611daf57600080fd5b505afa158015611dc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de7919061290e565b6040516001600160e01b031960e084901b168152600481019190915233602482015260440160206040518083038186803b158015611e2457600080fd5b505afa158015611e38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e5c91906128ee565b611e9d5760405162461bcd60e51b81526020600482015260126024820152712cb4b2b632283937bc3c9d1d10b0b236b4b760711b6044820152606401610362565b61197281612340565b611eae612858565b600060096000846001600160a01b03166001600160a01b031681526020019081526020016000206040518060e001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152505090506040518060e0016040528082600001518152602001826020015181526020018260400151815260200182606001518152602001826080015181526020018260a0015181526020018260c00151815250915050919050565b6040516001600160a01b0380851660248301528316604482015260648101829052611fff9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b0319909316929092179091526123f5565b50505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e9060440160206040518083038186803b15801561205157600080fd5b505afa158015612065573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612089919061290e565b6120939190612a0a565b6040516001600160a01b038516602482015260448101829052909150611fff90859063095ea7b360e01b90606401611fb3565b6001600160a01b0383166121425760405162461bcd60e51b815260206004820152603060248201527f636f6c6c65637461626c652d647573743a3a63616e742d73656e642d6475737460448201527f2d746f2d7a65726f2d61646472657373000000000000000000000000000000006064820152608401610362565b61214d6001836124da565b156121b25760405162461bcd60e51b815260206004820152602f60248201527f636f6c6c65637461626c652d647573743a3a746f6b656e2d69732d706172742d60448201526e1bd98b5d1a194b5c1c9bdd1bd8dbdb608a1b6064820152608401610362565b6001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415612213576040516001600160a01b0384169082156108fc029083906000818181858888f1935050505015801561220d573d6000803e3d6000fd5b50612227565b6122276001600160a01b0383168483612501565b604080516001600160a01b038086168252841660208201529081018290527f1e34c1aee8e83c2dcc14c21bb4bfeea7f46c0c998cb797ac7cc4d7a18f5c656b9060600160405180910390a1505050565b6122826001826124da565b6122f45760405162461bcd60e51b815260206004820152603060248201527f636f6c6c65637461626c652d647573743a3a746f6b656e2d6e6f742d7061727460448201527f2d6f662d7468652d70726f746f636f6c000000000000000000000000000000006064820152608401610362565b6122ff600182612531565b506040516001600160a01b03821681527fddd12a8c3ce9bea5c97a5d25c8b777caab85752828f56b7b8ad5a0b30340a25f906020015b60405180910390a150565b61234b6001826124da565b156123b05760405162461bcd60e51b815260206004820152602f60248201527f636f6c6c65637461626c652d647573743a3a746f6b656e2d69732d706172742d60448201526e1bd98b5d1a194b5c1c9bdd1bd8dbdb608a1b6064820152608401610362565b6123bb600182612546565b506040516001600160a01b03821681527fa3e4ba856dd0fdee3a33ab9b82499fd01f05236f3d08cc4e7108698c6e3e7e5090602001612335565b600061244a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661255b9092919063ffffffff16565b805190915015610da7578080602001905181019061246891906128ee565b610da75760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610362565b6001600160a01b038116600090815260018301602052604081205415155b90505b92915050565b6040516001600160a01b038316602482015260448101829052610da790849063a9059cbb60e01b90606401611fb3565b60006124f8836001600160a01b038416612574565b60006124f8836001600160a01b038416612691565b606061256a84846000856126e0565b90505b9392505050565b60008181526001830160205260408120548015612687576000612598600183612b78565b85549091506000906125ac90600190612b78565b905081811461262d5760008660000182815481106125da57634e487b7160e01b600052603260045260246000fd5b906000526020600020015490508087600001848154811061260b57634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255918252600188019052604090208390555b855486908061264c57634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506124fb565b60009150506124fb565b60008181526001830160205260408120546126d8575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556124fb565b5060006124fb565b6060824710156127585760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610362565b843b6127a65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610362565b600080866001600160a01b031685876040516127c2919061298a565b60006040518083038185875af1925050503d80600081146127ff576040519150601f19603f3d011682016040523d82523d6000602084013e612804565b606091505b509150915061281482828661281f565b979650505050505050565b6060831561282e57508161256d565b82511561283e5782518084602001fd5b8160405162461bcd60e51b815260040161036291906129d7565b6040518060e001604052806007906020820280368337509192915050565b600060208284031215612887578081fd5b813561256d81612bf4565b6000602082840312156128a3578081fd5b815161256d81612bf4565b6000806000606084860312156128c2578182fd5b83356128cd81612bf4565b925060208401356128dd81612bf4565b929592945050506040919091013590565b6000602082840312156128ff578081fd5b8151801515811461256d578182fd5b60006020828403121561291f578081fd5b5051919050565b600060208284031215612937578081fd5b5035919050565b600080600060608486031215612952578283fd5b505081359360208301359350604090920135919050565b60006020828403121561297a578081fd5b815160ff8116811461256d578182fd5b6000825161299c818460208701612bb2565b9190910192915050565b60e08101818360005b60078110156129ce5781518352602092830192909101906001016129af565b50505092915050565b60006020825282518060208401526129f6816040850160208701612bb2565b601f01601f19169190910160400192915050565b60008219821115612a1d57612a1d612bde565b500190565b600082612a3d57634e487b7160e01b81526012600452602481fd5b500490565b80825b6001808611612a545750612a7f565b818704821115612a6657612a66612bde565b80861615612a7357918102915b9490941c938002612a45565b94509492505050565b60006124f860001960ff851684600082612aa45750600161256d565b81612ab15750600061256d565b8160018114612ac75760028114612ad157612afe565b600191505061256d565b60ff841115612ae257612ae2612bde565b6001841b915084821115612af857612af8612bde565b5061256d565b5060208310610133831016604e8410600b8410161715612b31575081810a83811115612b2c57612b2c612bde565b61256d565b612b3e8484846001612a42565b808604821115612b5057612b50612bde565b02949350505050565b6000816000190483118215151615612b7357612b73612bde565b500290565b600082821015612b8a57612b8a612bde565b500390565b600060ff821660ff841680821015612ba957612ba9612bde565b90039392505050565b60005b83811015612bcd578181015183820152602001612bb5565b83811115611fff5750506000910152565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b038116811461197257600080fdfea164736f6c6343000803000a0000000000000000000000004da97a8b831c345dbe6d16ff7432df2b7b776d98000000000000000000000000eb801ab73e9a2a482aa48caca13b1954028f4c9400000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000056bc75e2d631000000000000000000000000000000000000000000000000000000000000000001388
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101765760003560e01c8063a734f06e116100d8578063e34bad3f1161008c578063fa3305c911610066578063fa3305c9146102c6578063fc0c546a146102d9578063ffdd5cf1146102f157610176565b8063e34bad3f146102a1578063f159e287146102aa578063f6f482aa146102b357610176565b8063be38a4fe116100bd578063be38a4fe14610268578063bf0d68e41461027b578063c4de21ff1461028e57610176565b8063a734f06e1461023c578063ada5b0df1461025757610176565b8063572af87d1161012f5780637e9bcdf5116101145780637e9bcdf514610222578063853828b61461022b5780639af1d35a1461023357610176565b8063572af87d1461020d5780635c975abb1461021757610176565b80632db8c129116101605780632db8c129146101b8578063481c6a75146101cb5780634d72b0a7146101f657610176565b8062aeef8a1461017b578063278188d6146101a3575b600080fd5b61018e61018936600461293e565b610311565b60405190151581526020015b60405180910390f35b6101b66101b1366004612926565b610a3e565b005b6101b66101c63660046128ae565b610c61565b600a546101de906001600160a01b031681565b6040516001600160a01b03909116815260200161019a565b6101ff60075481565b60405190815260200161019a565b6101ff620186a081565b60035460ff1661018e565b6101ff60055481565b61018e610dac565b6101ff60065481565b6101de73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b6101ff69021e19e0c9bab240000081565b6004546101de906001600160a01b031681565b6101b6610289366004612876565b61182e565b6101b661029c366004612926565b611975565b6101ff60085481565b6101ff61271081565b6101b66102c1366004612876565b611b07565b6101b66102d4366004612876565b611d62565b6003546101de9061010090046001600160a01b031681565b6103046102ff366004612876565b611ea6565b60405161019a91906129a6565b60006002600054141561036b5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b6002600055836103bd5760405162461bcd60e51b815260206004820152601560248201527f5969656c6450726f78793a3a616d6f756e743d3d3000000000000000000000006044820152606401610362565b33600090815260096020526040902080541561041b5760405162461bcd60e51b815260206004820152601560248201527f5969656c6450726f78793a3a4465706f457869737400000000000000000000006044820152606401610362565b6000808690506012600360019054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561047157600080fd5b505afa158015610485573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a99190612969565b60ff16101561055b57600360019054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561050057600080fd5b505afa158015610514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105389190612969565b610543906012612b8f565b61054e90600a612a88565b6105589088612b59565b90505b6008548510156105db57600069021e19e0c9bab2400000866007546105809190612b59565b61058a9190612a22565b9050620186a06006548961059e9190612b59565b6105a89190612a22565b9250600068056bc75e2d631000006105c08386612b59565b6105ca9190612a22565b90506105d68185612b78565b935050505b61271060006105eb600284612a22565b90508088101561066757600081610602818b612a0a565b6106159068056bc75e2d63100000612b59565b61061f9190612a22565b905068056bc75e2d63100000816005546106399190612b59565b6106439190612a22565b925061271083111561066557634e487b7160e01b600052600160045260246000fd5b505b600480860185905589865580546040805163760f5ebd60e11b815290516001600160a01b039092169263ec1ebd7a928282019260209290829003018186803b1580156106b257600080fd5b505afa1580156106c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ea919061290e565b600586015560028501889055600380860188905560068601839055546107209061010090046001600160a01b031633308c611f7f565b600480546040516370a0823160e01b815230928101929092526000916001600160a01b03909116906370a082319060240160206040518083038186803b15801561076957600080fd5b505afa15801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a1919061290e565b6004546003549192506107c69161010090046001600160a01b0390811691168c612005565b6004805460405163b6b55f2560e01b81529182018c90526001600160a01b03169063b6b55f2590602401600060405180830381600087803b15801561080a57600080fd5b505af115801561081e573d6000803e3d6000fd5b5050600480546040516370a0823160e01b815230928101929092528493506001600160a01b031691506370a082319060240160206040518083038186803b15801561086857600080fd5b505afa15801561087c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a0919061290e565b6108aa9190612b78565b600187015588156109525761095233308b600a60009054906101000a90046001600160a01b03166001600160a01b031663bc3ea0186040518163ffffffff1660e01b815260040160206040518083038186803b15801561090957600080fd5b505afa15801561091d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109419190612892565b6001600160a01b0316929190611f7f565b87156109ac576109ac33308a600a60009054906101000a90046001600160a01b03166001600160a01b031663b42165d06040518163ffffffff1660e01b815260040160206040518083038186803b15801561090957600080fd5b855460018701546004880154600589015460028a015460038b015460068c0154604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015233907f65b7b85cb51750af94dfd9985b1f2ab59acaeaf63a242f2415e0b4c84b657ee09060e00160405180910390a26001965050505050505060016000559392505050565b600a546040805163a217fddf60e01b815290516001600160a01b03909216916391d1485491839163a217fddf91600480820192602092909190829003018186803b158015610a8b57600080fd5b505afa158015610a9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac3919061290e565b6040516001600160e01b031960e084901b168152600481019190915233602482015260440160206040518083038186803b158015610b0057600080fd5b505afa158015610b14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3891906128ee565b610b795760405162461bcd60e51b81526020600482015260126024820152712cb4b2b632283937bc3c9d1d10b0b236b4b760711b6044820152606401610362565b600754811415610bcb5760405162461bcd60e51b815260206004820152601660248201527f5969656c6450726f78793a3a3d3d3d75627152617465000000000000000000006044820152606401610362565b69021e19e0c9bab2400000811115610c255760405162461bcd60e51b815260206004820152601760248201527f5969656c6450726f78793a3a3e756271526174654d41580000000000000000006044820152606401610362565b6007819055610c3e8169021e19e0c9bab2400000612a22565b610c49906064612b59565b610c5b90670de0b6b3a7640000612b59565b60085550565b600a546040805163a217fddf60e01b815290516001600160a01b03909216916391d1485491839163a217fddf91600480820192602092909190829003018186803b158015610cae57600080fd5b505afa158015610cc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce6919061290e565b6040516001600160e01b031960e084901b168152600481019190915233602482015260440160206040518083038186803b158015610d2357600080fd5b505afa158015610d37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5b91906128ee565b610d9c5760405162461bcd60e51b81526020600482015260126024820152712cb4b2b632283937bc3c9d1d10b0b236b4b760711b6044820152606401610362565b610da78383836120c6565b505050565b600060026000541415610e015760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610362565b600260009081553381526009602052604090208054610e625760405162461bcd60e51b815260206004820152601560248201527f5969656c6450726f78793a3a616d6f756e743d3d3000000000000000000000006044820152606401610362565b80546004808301546003546040805163313ce56760e01b8152905192936012936101009093046001600160a01b03169263313ce567928083019260209291829003018186803b158015610eb457600080fd5b505afa158015610ec8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eec9190612969565b60ff16101561104d57600360019054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610f4357600080fd5b505afa158015610f57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7b9190612969565b610f86906012612b8f565b610f9190600a612a88565b8354610f9d9190612b59565b9150600360019054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610fed57600080fd5b505afa158015611001573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110259190612969565b611030906012612b8f565b61103b90600a612a88565b836004015461104a9190612b59565b90505b60008360050154600460009054906101000a90046001600160a01b03166001600160a01b031663ec1ebd7a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110a257600080fd5b505afa1580156110b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110da919061290e565b6110e49085612b59565b6110ee9190612a22565b9050600080848311156111465760068601546127109061110e8786612b78565b6111189190612b59565b6111229190612a22565b91508361112f8685612b78565b6111399084612a0a565b6111439190612a0a565b90505b600060068701819055600487015487546111609190612b78565b60006004898101829055818a5560058a0191909155805460018a0154604051632e1a7d4d60e01b8152928301529192506001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b1580156111bf57600080fd5b505af11580156111d3573d6000803e3d6000fd5b5050600060018a015550506002870154156112f857600a60009054906101000a90046001600160a01b03166001600160a01b031663bc3ea0186040518163ffffffff1660e01b815260040160206040518083038186803b15801561123657600080fd5b505afa15801561124a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126e9190612892565b600288015460405163a9059cbb60e01b815233600482015260248101919091526001600160a01b03919091169063a9059cbb90604401602060405180830381600087803b1580156112be57600080fd5b505af11580156112d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f691906128ee565b505b6000600288015560038701541561141957600a60009054906101000a90046001600160a01b03166001600160a01b031663b42165d06040518163ffffffff1660e01b815260040160206040518083038186803b15801561135757600080fd5b505afa15801561136b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138f9190612892565b600388015460405163a9059cbb60e01b815233600482015260248101919091526001600160a01b03919091169063a9059cbb90604401602060405180830381600087803b1580156113df57600080fd5b505af11580156113f3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141791906128ee565b505b60006003888101919091555460405163a9059cbb60e01b8152336004820152602481018390526101009091046001600160a01b03169063a9059cbb90604401602060405180830381600087803b15801561147257600080fd5b505af1158015611486573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114aa91906128ee565b50600354600a546040805163c5f956af60e01b815290516001600160a01b0361010090940484169363a9059cbb93169163c5f956af916004808301926020929190829003018186803b1580156114ff57600080fd5b505afa158015611513573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115379190612892565b6003546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a082319060240160206040518083038186803b15801561157e57600080fd5b505afa158015611592573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b6919061290e565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b1580156115fc57600080fd5b505af1158015611610573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163491906128ee565b50600a5460408051630eb8f66960e21b815290516000926001600160a01b031691633ae3d9a4916004808301926020929190829003018186803b15801561167a57600080fd5b505afa15801561168e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116b29190612892565b6040516340c10f1960e01b8152306004820152602481018590529091506001600160a01b038216906340c10f1990604401600060405180830381600087803b1580156116fd57600080fd5b505af1158015611711573d6000803e3d6000fd5b505060405163a9059cbb60e01b8152336004820152602481018690526001600160a01b038416925063a9059cbb9150604401602060405180830381600087803b15801561175d57600080fd5b505af1158015611771573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061179591906128ee565b508754600189015460048a015460058b015460028c015460038d015460068e0154604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0810184905233907ff7cb8fce12fe949c9a4a6407e6d597806d10fc3b98b10b0d2de66b58e6e76cef906101000160405180910390a2600198505050505050505050600160005590565b600a546040805163a217fddf60e01b815290516001600160a01b03909216916391d1485491839163a217fddf91600480820192602092909190829003018186803b15801561187b57600080fd5b505afa15801561188f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b3919061290e565b6040516001600160e01b031960e084901b168152600481019190915233602482015260440160206040518083038186803b1580156118f057600080fd5b505afa158015611904573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192891906128ee565b6119695760405162461bcd60e51b81526020600482015260126024820152712cb4b2b632283937bc3c9d1d10b0b236b4b760711b6044820152606401610362565b61197281612277565b50565b600a546040805163a217fddf60e01b815290516001600160a01b03909216916391d1485491839163a217fddf91600480820192602092909190829003018186803b1580156119c257600080fd5b505afa1580156119d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119fa919061290e565b6040516001600160e01b031960e084901b168152600481019190915233602482015260440160206040518083038186803b158015611a3757600080fd5b505afa158015611a4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6f91906128ee565b611ab05760405162461bcd60e51b81526020600482015260126024820152712cb4b2b632283937bc3c9d1d10b0b236b4b760711b6044820152606401610362565b600654811415611b025760405162461bcd60e51b815260206004820152601360248201527f5969656c6450726f78793a3a3d3d3d66656573000000000000000000000000006044820152606401610362565b600655565b600a546040805163a217fddf60e01b815290516001600160a01b03909216916391d1485491839163a217fddf91600480820192602092909190829003018186803b158015611b5457600080fd5b505afa158015611b68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8c919061290e565b6040516001600160e01b031960e084901b168152600481019190915233602482015260440160206040518083038186803b158015611bc957600080fd5b505afa158015611bdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0191906128ee565b611c425760405162461bcd60e51b81526020600482015260126024820152712cb4b2b632283937bc3c9d1d10b0b236b4b760711b6044820152606401610362565b6001600160a01b038116611c985760405162461bcd60e51b815260206004820152601060248201527f5969656c6450726f78793a3a214a6172000000000000000000000000000000006044820152606401610362565b600480547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038316908117825560408051637e062a3560e11b81529051919263fc0c546a928282019260209290829003018186803b158015611d0157600080fd5b505afa158015611d15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d399190612892565b600360016101000a8154816001600160a01b0302191690836001600160a01b0316021790555050565b600a546040805163a217fddf60e01b815290516001600160a01b03909216916391d1485491839163a217fddf91600480820192602092909190829003018186803b158015611daf57600080fd5b505afa158015611dc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de7919061290e565b6040516001600160e01b031960e084901b168152600481019190915233602482015260440160206040518083038186803b158015611e2457600080fd5b505afa158015611e38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e5c91906128ee565b611e9d5760405162461bcd60e51b81526020600482015260126024820152712cb4b2b632283937bc3c9d1d10b0b236b4b760711b6044820152606401610362565b61197281612340565b611eae612858565b600060096000846001600160a01b03166001600160a01b031681526020019081526020016000206040518060e001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152505090506040518060e0016040528082600001518152602001826020015181526020018260400151815260200182606001518152602001826080015181526020018260a0015181526020018260c00151815250915050919050565b6040516001600160a01b0380851660248301528316604482015260648101829052611fff9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b0319909316929092179091526123f5565b50505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e9060440160206040518083038186803b15801561205157600080fd5b505afa158015612065573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612089919061290e565b6120939190612a0a565b6040516001600160a01b038516602482015260448101829052909150611fff90859063095ea7b360e01b90606401611fb3565b6001600160a01b0383166121425760405162461bcd60e51b815260206004820152603060248201527f636f6c6c65637461626c652d647573743a3a63616e742d73656e642d6475737460448201527f2d746f2d7a65726f2d61646472657373000000000000000000000000000000006064820152608401610362565b61214d6001836124da565b156121b25760405162461bcd60e51b815260206004820152602f60248201527f636f6c6c65637461626c652d647573743a3a746f6b656e2d69732d706172742d60448201526e1bd98b5d1a194b5c1c9bdd1bd8dbdb608a1b6064820152608401610362565b6001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415612213576040516001600160a01b0384169082156108fc029083906000818181858888f1935050505015801561220d573d6000803e3d6000fd5b50612227565b6122276001600160a01b0383168483612501565b604080516001600160a01b038086168252841660208201529081018290527f1e34c1aee8e83c2dcc14c21bb4bfeea7f46c0c998cb797ac7cc4d7a18f5c656b9060600160405180910390a1505050565b6122826001826124da565b6122f45760405162461bcd60e51b815260206004820152603060248201527f636f6c6c65637461626c652d647573743a3a746f6b656e2d6e6f742d7061727460448201527f2d6f662d7468652d70726f746f636f6c000000000000000000000000000000006064820152608401610362565b6122ff600182612531565b506040516001600160a01b03821681527fddd12a8c3ce9bea5c97a5d25c8b777caab85752828f56b7b8ad5a0b30340a25f906020015b60405180910390a150565b61234b6001826124da565b156123b05760405162461bcd60e51b815260206004820152602f60248201527f636f6c6c65637461626c652d647573743a3a746f6b656e2d69732d706172742d60448201526e1bd98b5d1a194b5c1c9bdd1bd8dbdb608a1b6064820152608401610362565b6123bb600182612546565b506040516001600160a01b03821681527fa3e4ba856dd0fdee3a33ab9b82499fd01f05236f3d08cc4e7108698c6e3e7e5090602001612335565b600061244a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661255b9092919063ffffffff16565b805190915015610da7578080602001905181019061246891906128ee565b610da75760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610362565b6001600160a01b038116600090815260018301602052604081205415155b90505b92915050565b6040516001600160a01b038316602482015260448101829052610da790849063a9059cbb60e01b90606401611fb3565b60006124f8836001600160a01b038416612574565b60006124f8836001600160a01b038416612691565b606061256a84846000856126e0565b90505b9392505050565b60008181526001830160205260408120548015612687576000612598600183612b78565b85549091506000906125ac90600190612b78565b905081811461262d5760008660000182815481106125da57634e487b7160e01b600052603260045260246000fd5b906000526020600020015490508087600001848154811061260b57634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255918252600188019052604090208390555b855486908061264c57634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506124fb565b60009150506124fb565b60008181526001830160205260408120546126d8575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556124fb565b5060006124fb565b6060824710156127585760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610362565b843b6127a65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610362565b600080866001600160a01b031685876040516127c2919061298a565b60006040518083038185875af1925050503d80600081146127ff576040519150601f19603f3d011682016040523d82523d6000602084013e612804565b606091505b509150915061281482828661281f565b979650505050505050565b6060831561282e57508161256d565b82511561283e5782518084602001fd5b8160405162461bcd60e51b815260040161036291906129d7565b6040518060e001604052806007906020820280368337509192915050565b600060208284031215612887578081fd5b813561256d81612bf4565b6000602082840312156128a3578081fd5b815161256d81612bf4565b6000806000606084860312156128c2578182fd5b83356128cd81612bf4565b925060208401356128dd81612bf4565b929592945050506040919091013590565b6000602082840312156128ff578081fd5b8151801515811461256d578182fd5b60006020828403121561291f578081fd5b5051919050565b600060208284031215612937578081fd5b5035919050565b600080600060608486031215612952578283fd5b505081359360208301359350604090920135919050565b60006020828403121561297a578081fd5b815160ff8116811461256d578182fd5b6000825161299c818460208701612bb2565b9190910192915050565b60e08101818360005b60078110156129ce5781518352602092830192909101906001016129af565b50505092915050565b60006020825282518060208401526129f6816040850160208701612bb2565b601f01601f19169190910160400192915050565b60008219821115612a1d57612a1d612bde565b500190565b600082612a3d57634e487b7160e01b81526012600452602481fd5b500490565b80825b6001808611612a545750612a7f565b818704821115612a6657612a66612bde565b80861615612a7357918102915b9490941c938002612a45565b94509492505050565b60006124f860001960ff851684600082612aa45750600161256d565b81612ab15750600061256d565b8160018114612ac75760028114612ad157612afe565b600191505061256d565b60ff841115612ae257612ae2612bde565b6001841b915084821115612af857612af8612bde565b5061256d565b5060208310610133831016604e8410600b8410161715612b31575081810a83811115612b2c57612b2c612bde565b61256d565b612b3e8484846001612a42565b808604821115612b5057612b50612bde565b02949350505050565b6000816000190483118215151615612b7357612b73612bde565b500290565b600082821015612b8a57612b8a612bde565b500390565b600060ff821660ff841680821015612ba957612ba9612bde565b90039392505050565b60005b83811015612bcd578181015183820152602001612bb5565b83811115611fff5750506000910152565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b038116811461197257600080fdfea164736f6c6343000803000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004da97a8b831c345dbe6d16ff7432df2b7b776d98000000000000000000000000eb801ab73e9a2a482aa48caca13b1954028f4c9400000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000056bc75e2d631000000000000000000000000000000000000000000000000000000000000000001388
-----Decoded View---------------
Arg [0] : _manager (address): 0x4DA97a8b831C345dBe6d16FF7432DF2b7b776d98
Arg [1] : _jar (address): 0xEB801AB73E9A2A482aA48CaCA13B1954028F4c94
Arg [2] : _fees (uint256): 10000
Arg [3] : _ubqRate (uint256): 100000000000000000000
Arg [4] : _bonusYield (uint256): 5000
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000004da97a8b831c345dbe6d16ff7432df2b7b776d98
Arg [1] : 000000000000000000000000eb801ab73e9a2a482aa48caca13b1954028f4c94
Arg [2] : 0000000000000000000000000000000000000000000000000000000000002710
Arg [3] : 0000000000000000000000000000000000000000000000056bc75e2d63100000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000001388
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.