Depot¶
Work in Progress
This needs to be properly cleaned up.
Description¶
Old: Depot.sol: Allows users to exchange BNB for oUSD and OKS (has not yet been updated for multicurrency).
Throughout, the contract assumes that oUSD is always worth exactly US$1. So: a) this will only work with oUSD
. b) there's a profit opportunity if the oUSD
is off its peg.
Note
Some of this code is lifted verbatim from the old EtherNomin
code, but this isn't indicated in the licence header.
Zero Transfer Fee
SIP-19 deprecated transfer fees. Hence, although exchange operations call FeePool.amountReceivedFromTransfer
to subtract this fee from the sale quantity, the fee function just returns its argument unchanged, so nothing is actually charged.
Source: Depot.sol
Architecture¶
Inheritance Graph¶
Related Contracts¶
Libraries¶
SafeMath
foruint
SafeDecimalMath
foruint
Structs¶
synthDeposit
¶
Stores an individual Synth deposit on sale.
Field | Type | Description |
---|---|---|
user | address |
The depositor. |
amount | uint |
The quantity of oUSD deposited. |
Variables¶
oikos
¶
The address of the main Oikos
contract; the depot contains OKS.
Type: Oikos public
synth
¶
The address of the oUSD Synth
, which are the synth held in the depot.
Type: Synth public
feePool
¶
The address of the FeePool
contract. Since transfer fees were eliminated in SIP-19, this is not really used anymore. All the fee pool functions this contract calls have now been replaced with effective no-ops.
Type: FeePool public
fundsWallet
¶
The address where ether and synths raised by selling OKS are sent.
It is also where ether is sent if the proceeds of a sale of synths could not be transferred because the recipient is a non-payable contract.
Type: address public
oracle
¶
The address which provides the usd prices of OKS and ether. This is not the same oracle address as in ExchangeRates
.
Type: address public
ORACLE_FUTURE_LIMIT
¶
The oracle can submit prices no more than ten minutes into the future.
Type: uint public constant
Value: 10 minutes
priceStalePeriod
¶
It is assumed the known price is out of date if it is older than this. Initialised to 3 hours.
Type: uint public
lastPriceUpdateTime
¶
The last time usdToSnxPrice
and usdToEthPrice
were updated by the oracle
calling updatePrices
.
Type: uint public
usdToSnxPrice
¶
The price of OKS in USD.
Type: uint public
(18 decimals)
usdToEthPrice
¶
The price of BNB in USD.
Type: uint public
(18 decimals)
deposits
¶
Users can deposit oUSD to be sold on the depot. This variable holds the queue of open deposits, which are sold in the order they were deposited.
This queue is stored as an "array" within a mapping: the keys are array indices. Deposits are stored by a contiguous block of keys between depositStartIndex
(inclusive) and depositEndIndex
(exclusive).
A mapping is used instead of an array in order to avoid having to copy entries around when deposits are deleted, which saves on gas. When a deposit is made it is added to the end of the list, and when a deposit is filled, it is removed from the start of the list. Thus over time the list of deposits slides down the set of array indexes, but the address space of the mapping is large enough that it will never be filled.
Type: mapping(uint => synthDeposit) public
depositStartIndex
¶
The index of the next deposit to be processed in the deposits
queue.
Type: uint public
depositEndIndex
¶
The index one past the last deposit in the deposits
queue.
Type: uint public
totalSellableDeposits
¶
The total quantity of oUSD currently in the deposits
queue to be purchased.
Type: uint public
(18 decimals)
minimumDepositAmount
¶
The minimum oUSD quantity required for a deposit to be added to the queue. Initialised to 50.0.
Type: uint public
(18 decimals)
smallDeposits
¶
Deposits of less than minimumDepositAmount
oUSD are not placed on the deposits
queue. Instead, they are kept here so that the depositor can withdraw them.
Type: mapping(address => uint) public
(18 decimals)
Functions¶
constructor
¶
Initialises the various addresses this contract knowws, along with the initial prices and the inherited SelfDestructible
and Pausable
instances.
Details
Signature
constructor(address _owner, address _fundsWallet, Oikos _oikos, Synth _synth, FeePool _feePool, address _oracle, uint _usdToEthPrice, uint _usdToSnxPrice) public
Superconstructors
setFundsWallet
¶
Allows the owner to set the fundsWallet
address.
Details
Signature
setFundsWallet(address _fundsWallet) external
Modifiers
Emits
setOracle
¶
Allows the owner to set the oracle
address.
Details
Signature
setOracle(address _oracle) external
Modifiers
Emits
setSynth
¶
Allows the owner to set the address of the synth
contract the depot knows about.
Details
Signature
setSynth(Synth _synth) external
Modifiers
Emits
setOikos
¶
Allows the owner to set the address of the oikos
contract.
setPriceStalePeriod
¶
Allows the owner to set the stale period for depot prices.
Details
Signature
setPriceStalePeriod(uint _time)
Modifiers
Emits
setMinimumDepositAmount
¶
Allows the owner to set the minimum deposit amount.
Details
Signature
setMinimumDepositAmount(uint _amount)
Modifiers
Preconditions
_amount
must be greater thanUNIT
.
Emits
updatePrices
¶
Allows the oracle address to update the USD BNB and OKS prices known to the depot.
The prices are accompanied by the time they were sent. The oracle will not accept updates that are not the most recent, otherwise which protects from accepting stale prices during network congestion.
Details
Signature
updatePrices(uint newEthPrice, uint newOikosPrice, uint timeSent) external
Modifiers
Preconditions
- The time the price update was sent must be after the last price update time.k
- The time the price update was sent must be no more than ten minutes in the future.
Emits
() (fallback function)
¶
This simply calls exchangeEtherForSynths
so that if ether is sent to the contract, it is automatically exchanged for synths.
Details
Signature
() external payable
exchangeEtherForSynths
¶
Sells oUSD to callers who send ether. The synths are sold from the deposits
queue in the order they were deposited.
Purchased quantity: msg.value * usdToEthPrice
Each deposit is sold in turn until the full This function if invoked with a
Requires that the contract is not paused, and that the prices are not stale.
Returns the number of oUSD exchanged. Converts any ether sent to the contract to a quantity of synths at current prices. Fulfils this quantity by iterating through the deposit queue until the entire quantity is found. If a given deposit is insufficient to cover the entire requested amount, it is exhausted and removed from the queue. For each deposit found, the proper quantity of ether is sent to the depositor. If the quantity could not be sent because the target is a non-payable contract, then it is remitted to fundsWallet
. Then send the Synths to the recipient. If the whole quantity could not be fulfilled, then the remaining ether is refunded to the purchaser.
exchangeEtherForSynths() returns (uint)
:
exchangeEtherForSynthsAtRate
¶
exchangeEtherForSynthsAtRate(uint guaranteedRate) returns (uint)
: Allows the caller to specify the current price, and then calls toexchangeEtherForSynths
. Reverts if the current price does not match the price provided as an argument. This is intended as a protection against front-running by the contract owner, or otherwise a case where a price update is in flight at the invocation time.
exchangeEtherForOikos
¶
exchangeEtherForOikos() returns (uint)
: Requires that the contract is not paused, and that the prices are not stale. Converts the received ether to a quantity of OKS withoikosReceivedForEther
. Sends the ether tofundsWallet
, sends the converted quantity of OKS to the message sender from the contract's own reserves. Returns the OKS quantity sent. If the contract has insufficient OKS, then the transfer will fail and the transaction will revert.
exchangeEtherForOikosAtRate
¶
exchangeEtherForOikosAtRate(uint guaranteedEtherRate, uint guaranteedSynthetixRate) returns (uint)
: AsexchangeEtherForSynthsAtRate
is toexchangeEtherForSynths
, this is toexchangeEtherForSynthetix
.
exchangeSynthsForOikos
¶
exchangeSynthsForOikos(uint synthAmount) returns (uint)
: Identical toexchangeEtherForSynthetix
, but perform the price conversion withoikosReceivedForSynths
. The amount of synths to send is provided as a function argument, and then transferred tofundsWallet
withtransferFrom
, so this function requires the caller to have approved the depot contract to make such a withdrawal. Note that this assumes that oUSD is worth exactly one dollar.
exchangeSynthsForOikosAtRate
¶
exchangeSynthsForOikosAtRate(uint synthAmount, uint guaranteedRate) returns (uint)
: As perexchangeEtherForSynthetixAtRate
.
withdrawOikos
¶
withdrawOikos(uint amount)
: Only callable by the contract owner. Allows the owner to transfer OKS out of the Depot to themselves.
withdrawMyDepositedSynths
¶
withdrawMyDepositedSynths()
: Withdraws all Synths deposited by the message sender. Iterates through the entire deposit queue; if for a given entry the message sender is the depositor, delete that deposit and and add the deposited quantity of tokens to the pile to be remitted. Then transfer this quantity back to the message sender, along with any tokens insmallDeposits
.
depositSynths
¶
depositSynths(uint amount)
: Just an alias tosynth.transferFrom(msg.sender, this, amount)
. This requires the sender to have approved the deposit.
tokenFallback
¶
tokenFallback(address from, uint amount, bytes data) returns (bool)
: Only callable by thesynth
contract. Handles the actual deposit flow whenever synths are sent to this contract. If the transferred quantity is smaller than the minimum deposit amount, add it to the sender's small deposit balance. Otherwise, "append" the deposit to the deposit queue/mapping and update total sellable deposit quantity.
pricesAreStale
¶
True if usdToSnxPrice
and usdToEthPrice
are too old to be considered usably up to date.
That is, they are considered stale if lastPriceUpdateTime
is more than priceStalePeriod
seconds in the past.
If prices are stale, then the depot's exchange functionality is disabled. This is because attackers can profitably exploit the contract if the prices known on chain do not reflect the true state of the world closely enough.
Details
Signature
pricesAreStale() public view returns (bool)
oikosReceivedForSynths
¶
Computes the quantity of OKS received in exchange for a given quantity of oUSD at current prices, assuming oUSD are worth $1. This is equivalent to:
Details
Signature
oikosReceivedForSynths(uint amount) public view returns (uint)
oikosReceivedForEther
¶
Computes the quantity of OKS received in exchange for a given quantity of Ether at current prices. This is equivalent to:
Details
Signature
oikosReceivedForEther(uint amount) public view returns (uint)
synthsReceivedForEther
¶
Computes the quantity of oUSD received in exchange for a given quantity of BNB at current prices. This is equivalent to:
Details
Signature
synthsReceivedForEther(uint amount) public view returns (uint)
Modifiers¶
onlyOracle
¶
Reverts the transaction if msg.sender
is not the oracle
address.
onlySynth
¶
Reverts the transaction if msg.sender
is not the synth
address.
pricesNotStale
¶
Reverts the transaction if pricesAreStale
returns false, because the contract's known prices are too old to safely use.
Events¶
FundsWalletUpdated
¶
FundsWalletUpdated(address newFundsWallet)
OracleUpdated
¶
OracleUpdated(address newOracle)
SynthUpdated
¶
SynthUpdated(Synth newSynthContract)
OikosUpdated
¶
OikosUpdated(Synthetix newSynthetixContract)
PriceStalePeriodUpdated
¶
PriceStalePeriodUpdated(uint priceStalePeriod)
PricesUpdated
¶
PricesUpdated(uint newEthPrice, uint newOikosPrice, uint timeSent)
Exchange
¶
Exchange(string fromCurrency, uint fromAmount, string toCurrency, uint toAmount)
SynthWithdrawal
¶
SynthWithdrawal(address user, uint amount)
SynthDeposit
¶
SynthDeposit(address indexed user, uint amount, uint indexed depositIndex)
SynthDepositRemoved
¶
SynthDepositRemoved(address indexed user, uint amount, uint indexed depositIndex)
SynthDepositNotAccepted
¶
SynthDepositNotAccepted(address user, uint amount, uint minimum)
SynthDepositAmountUpdated
¶
MinimumDepositAmountUpdated(uint amount)
NonPayableContract
¶
NonPayableContract(address indexed receiver, uint amount)
ClearedDeposit
¶
ClearedDeposit(address indexed fromAddress, address indexed toAddress, uint fromBNBAmount, uint toAmount, uint indexed depositIndex)