Synth¶
This contract is the basis of all Synth flavours.
It exposes sufficient functionality for the Oikos
and FeePool
contracts to manage its supply. Otherwise Synths are fairly vanilla ERC20 tokens; the PurgeableSynth
contract extends this basic functionality to allow the owner to liquidate a Synth if its total value is low enough.
See the main synth notes for more information about how Synths function in practice.
A Note on Conversion Fees
Since transfer conversion is not operating, the following is recorded only to be kept in mind in case it is ever reactivated. At present there is no way for users to set a preferred currency.
The Oikos system has implements both exchange and transfer fees on Synths. Although they should be distinct, the preferred currency auto conversion on transfer only charges the transfer fee, and not the exchange fee. As a result, it is possible to convert Synths more cheaply whenever the transfer fee is less than the conversion fee.
Given that the transfer fee is currently nil, if a user was able to set a preferred currency for themselves, it would be possible by this means to perform free Synth conversions. This would undercut fee revenue for the system to incentivise participants with. If markets had priced in the conversion fee, but were unaware of the exploit, then there would be a profit cycle available for someone exploiting this.
In particular:
Let \phi_\kappa, \ \phi_\tau \in [0,1] be the conversion and transfer fee rates, respectively. Let \pi_A, \ \pi_B be the prices of synths A and B in terms of some implicit common currency. Q_A will be the starting quantity of synth A.
Then to convert from A to B, quantities
are received if the user performs a standard conversion or a transfer conversion, respectively. The profit of performing a transfer conversion relative to a standard one is then:
That is, the relative profit is simply (\phi_\kappa - \phi_\tau). With no transfer fee, this is \phi_\kappa, as expected.
Source: Synth.sol
Architecture¶
Inheritance Graph¶
Variables¶
feePool
¶
The address of the FeePool
contract.
Type: FeePool public
oikos
¶
The address of the Oikos
contract.
Type: FeePool public
currencyKey
¶
The identifier of this Synth within the Oikos ecosystem. The currency key could in principle be distinct from this token's ERC20 symbol.
Type: bytes32
DECIMALS
¶
The number of decimal places this token uses. Fixed at 18.
Type: uint8 constant
Value: 18
Functions¶
constructor
¶
Initialises the feePool
and oikos
addresses, this Synth's currencyKey
, and the inherited ExternStateToken
instance.
The precision in every Synth's fixed point representation is fixed at 18 so they are all conveniently interconvertible. The total supply of all new Synths is initialised to 0 since they must be created by the Oikos
contract when issuing or converting between Synths, or by the FeePool
when users claim fees.
Details
Signature
constructor(address _proxy, TokenState _tokenState, Oikos _oikos, IFeePool _feePool, string _tokenName, string _tokenSymbol, address _owner, bytes32 _currencyKey) public
Superconstructors
Preconditions
- The provided proxy, oikos, fee pool, and owner addresses must not be zero.
- The provided currency key must not already be registered on oikos.
setOikos
¶
Allows the owner to set the address of the oikos
contract.
Details
Signature
setOikos(Oikos _oikos) external
Modifiers
Emits
setFeePool
¶
Allows the owner to set the address of the feePool
contract.
Details
Signature
setFeePool(FeePool _feePool) external
Modifiers
Emits
transfer
¶
This is a pair of ERC20 transfer function.
Implemented based on ExternStateToken._transfer_byProxy
.
Warning
This will always fail if there are any exchanges awaiting settlement for this synth. To prevent failues, please use transferAndSettle()
below or invoke Exchanger.settle()
prior to transfer()
.
Details
Signatures
transfer(address to, uint value) public returns (bool)
Modifiers
transferAndSettle
¶
Settles any outstanding fee reclaims and rebates and then performs the transfer
functionality. If there is insufficient balance to transfer value
after any reclaims, the amount
will be reduced to the remaining balance of the sender.
Implemented based on ExternStateToken._transfer_byProxy
.
Details
Signatures
transfer(address to, uint value) public returns (bool)
Modifiers
transferFrom
¶
This is a ERC20 transferFrom function.
Implemented based on ExternStateToken._transferFrom_byProxy
.
Warning
This will always fail if there are any exchanges awaiting settlement for this synth. To prevent failues, please use transferFromAndSettle()
below or invoke Exchanger.settle()
prior to transferFrom()
.
Details
Signatures
transferFrom(address from, address to, uint value) public returns (bool)
Modifiers
transferFromAndSettle
¶
Settles any outstanding fee reclaims and rebates and then performs the transferFrom
functionality. If there is insufficient balance to transfer value
after any reclaims, the amount
will be reduced to the remaining balance of the from
address.
Implemented based on ExternStateToken._transferFrom_byProxy
.
Warning
This will always fail if there are any exchanges awaiting settlement for this synth. To prevent failues, please use transferFromAndSettle()
below or invoke Exchanger.settle()
prior to transferFrom()
.
Details
Signatures
transferFrom(address from, address to, uint value) public returns (bool)
Modifiers
_internalTransfer
¶
This function implements all of the other ERC20 transfer functions supported by this contract. It is itself simply a wrapper to ExternStateToken._internalTransfer
.
Dormant Preferred Currency Conversion
If OikosState.preferredCurrency(to)
is nonzero, this function automatically performs an exchange into the preferred Synth flavour using Oikos.synthInitiatedExchange
. However, there is currently no way for accounts to set their preferred currency, so this feature has effectively been deactivated.
Details
Signature
_internalTransfer(address from, address to, uint value) internal returns (bool)
Preconditions and Events
issue
¶
Allows the Oikos
contract to issue new Synths of this flavour. This is used whenever Synths are exchanged or issued directly. This is also used by the FeePool
to pay fees out.
Details
Signature
issue(address account, uint amount) external
Modifiers
Emits
burn
¶
Allows the Oikos
contract to burn existing Synths of this flavour. This is used whenever Synths are exchanged or burnt directly. This is also used to burn Synths involved in oracle frontrunning as part of the protection circuit. This is also used by the FeePool
to burn oUSD when fees are paid out.
Details
Signature
burn(address account, uint amount) external
Modifiers
Emits
setTotalSupply
¶
This allows the owner to set the total supply directly for upgrades, where the tokenState
is retained, but the total supply figure must be migrated.
For example, just such a migration is performed by this script.
Modifiers¶
onlyOikosOrFeePool
¶
Reverts the transaction if the msg.sender
is neither oikos
nor feePool
.
Signature: notFeeAddress(address account)
Events¶
OikosUpdated
¶
Records that the oikos
address was updated.
This event is emitted from the Synths's proxy with the emitOikosUpdated
function.
Signature: OikosUpdated(address newOikos)
FeePoolUpdated
¶
Records that the feePool
address was updated.
This event is emitted from the Synths's proxy with the emitFeePoolUpdated
function.
Signature: FeePoolUpdated(address newFeePool)
Issued
¶
Records that a quantity of this Synth was newly issued.
This event is emitted from the Synths's proxy with the emitIssued
function.
Signature: Issued(address indexed account, uint value)
Burned
¶
Records that a quantity of this Synth was burned.
This event is emitted from the Synths's proxy with the emitBurned
function.
Signature: Burned(address indexed account, uint value)