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

## 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.

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)