Skip to content

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

Q^\kappa_B = Q_A\frac{\pi_A}{\pi_B}(1 - \phi_\kappa) \\ Q^\tau_B = Q_A\frac{\pi_A}{\pi_B}(1 - \phi_\tau)

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:

Q^\tau_B - Q^\kappa_B = Q_A\frac{\pi_A}{\pi_B}(\phi_\kappa - \phi_\tau)

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

Synth 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

As per ExternStateToken._internalTransfer.


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.

Details

Signature

setTotalSupply(uint amount) external

Modifiers


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)