Synthetix Solidity smart contracts
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
Go to file
kaleb cac454dcd4
Update steth eth goerli feed (#2151)
Co-authored-by: Leonardo Massazza <lmassazza@gmail.com>
3 weeks ago
.circleci SIP-2004 & SIP-2005 New features & Improvements (#1994) 6 months ago
.github/workflows ci: use dockerhub for slither (#1912) 12 months ago
contracts Sabik release v2.94.1 (#2148) 4 weeks ago
examples Consolidating on ProxySynthetix and ProxysUSD (#1704) 2 years ago
hardhat SIP-2004 & SIP-2005 New features & Improvements (#1994) 6 months ago
hooks Improve lint hook (#1140) 3 years ago
publish Update steth eth goerli feed (#2151) 3 weeks ago
test Update perps v2 config (#2109) 3 months ago
.env.example Diphda release 2.64.0 to mainnet (#1729) 2 years ago
.eslintignore add optimism folder to eslintignore file (#1406) 2 years ago
.eslintrc.js Kochab release 2.71.2 (#1801) 1 year ago
.gitattributes Migration to hardhat 👷 and the resumption of coverage 💥 (#914) 3 years ago
.gitignore Tiaki release v2.75.2 (#1857) 1 year ago
.npmrc Denebola release v2.73.1 to mainnet (#1817) 1 year ago
.nvmrc Alkaid release to mainnet v2.53 (#1603) 2 years ago
.prettierignore Add circleci paths to prettierignore for pretty-quick (#921) 3 years ago
.prettierrc Release develop into staging for Mimosa (2.31.x) (#877) 3 years ago
.solcover.js Naos v2.84.4 release to mainnet (#2053) 6 months ago
.solhint.json Removing reason-string check 3 years ago
LICENSE Update LICENSE 4 years ago
README.md Ankaa release v2.91.1 (#2121) 2 months ago
bin.js Naos v2.84.4 release to mainnet (#2053) 6 months ago
browser.js.LICENSE.txt Naos v2.84.4 release to mainnet (#2053) 6 months ago
cannonfile.aggregator.toml Tiaki release v2.75.2 (#1857) 1 year ago
cannonfile.optimism.toml Update cannonfile.optimism.toml 4 months ago
cannonfile.release.toml Update Cannon to v.1.1.x (#1891) 11 months ago
cannonfile.toml Naos v2.84.4 release to mainnet (#2053) 6 months ago
codechecks.unit.yml Add gas reporting job parallelization on CI (#1305) 2 years ago
codecov.yml Kaus release v2.51 (#1574) 2 years ago
hardhat.config.js Naos v2.84.4 release to mainnet (#2053) 6 months ago
index.js Ankaa release v2.91.1 (#2121) 2 months ago
output.txt Removed web3 from extract-staking-balances (#1335) 2 years ago
output_new.txt Removed web3 from extract-staking-balances (#1335) 2 years ago
package-lock.json Merge branch 'master' into develop 4 weeks ago
package.json 2.94.1 4 weeks ago
safe.js Tiaki release v2.75.2 (#1857) 1 year ago
slither.config.json Alsephina release v2.58 (#1675) 2 years ago
webpack.config.js Naos v2.84.4 release to mainnet (#2053) 6 months ago

README.md

Synthetix

CircleCI codecov npm version Discord Twitter Follow

Synthetix is a crypto-backed synthetic asset platform.

It is a multi-token system, powered by SNX, the Synthetix Network Token. SNX holders can stake SNX to issue Synths, on-chain synthetic assets via the Staking dApp The network currently supports an ever-growing list of synthetic assets. Please see the list of the deployed contracts on MAIN and TESTNETS Synths can be traded using Kwenta

Synthetix uses a proxy system so that upgrades will not be disruptive to the functionality of the contract. This smooths user interaction, since new functionality will become available without any interruption in their experience. It is also transparent to the community at large, since each upgrade is accompanied by events announcing those upgrades. New releases are managed via the Synthetix Improvement Proposal (SIP) system similar to the EIPs

Prices are committed on-chain by a trusted oracle provided by Chainlink.

Please note that this repository is under development.

For the latest system documentation see docs.synthetix.io

DApps

Community

Discord Twitter Follow

For a guide from the community, see synthetix.community


Repo Guide

Branching

A note on the branches used in this repo.

  • master represents the contracts live on mainnet and all testnets.

When a new version of the contracts makes its way through all testnets, it eventually becomes promoted in master, with semver reflecting contract changes in the major or minor portion of the version (depending on backwards compatibility). patch changes are simply for changes to the JavaScript interface.

Testing

CircleCI codecov

Please see docs.synthetix.io/contracts/testing for an overview of the automated testing methodologies.

Module Usage

npm version

This repo may be installed via npm install to support both node.js scripting applications and Solidity contract development.

Examples

💯 Please see our walkthroughs for code examples in both JavaScript and Solidity: docs.synthetix.io/integrations

Solidity API

All interfaces are available via the path synthetix/contracts/interfaces.

In your code, the key is to use IAddressResolver which can be tied to the immutable proxy: ReadProxyAddressResolver (introduced in SIP-57). You can then fetch Synthetix, FeePool, Depot, et al via IAddressResolver.getAddress(bytes32 name) where name is the bytes32 version of the contract name (case-sensitive). Or you can fetch any synth using IAddressResolver.getSynth(bytes32 synth) where synth is the bytes32 name of the synth (e.g. iETH, sUSD, sDEFI).

E.g.

npm install synthetix

then you can write Solidity as below (using a compiler that links named imports via node_modules):

pragma solidity 0.5.16;

import 'synthetix/contracts/interfaces/IAddressResolver.sol';
import 'synthetix/contracts/interfaces/ISynthetix.sol';

contract MyContract {
  // This should be instantiated with our ReadProxyAddressResolver
  // it's a ReadProxy that won't change, so safe to code it here without a setter
  // see https://docs.synthetix.io/addresses for addresses in mainnet and testnets
  IAddressResolver public synthetixResolver;

  constructor(IAddressResolver _snxResolver) public {
    synthetixResolver = _snxResolver;
  }

  function synthetixIssue() external {
    ISynthetix synthetix = synthetixResolver.getAddress('Synthetix');
    require(synthetix != address(0), 'Synthetix is missing from Synthetix resolver');

    // Issue for msg.sender = address(MyContract)
    synthetix.issueMaxSynths();
  }

  function synthetixIssueOnBehalf(address user) external {
    ISynthetix synthetix = synthetixResolver.getAddress('Synthetix');
    require(synthetix != address(0), 'Synthetix is missing from Synthetix resolver');

    // Note: this will fail if `DelegateApprovals.approveIssueOnBehalf(address(MyContract))` has
    // not yet been invoked by the `user`
    synthetix.issueMaxSynthsOnBehalf(user);
  }
}

Node.js API

  • getAST({ source, match = /^contracts\// }) Returns the Abstract Syntax Tree (AST) for all compiled sources. Optionally add source to restrict to a single contract source, and set match to an empty regex if you'd like all source ASTs including third-party contracts
  • getPathToNetwork({ network, file = '' }) Returns the path to the folder (or file within the folder) for the given network
  • getSource({ network }) Return abi and bytecode for a contract source
  • getSuspensionReasons({ code }) Return mapping of SystemStatus suspension codes to string reasons
  • getStakingRewards({ network }) Return the list of staking reward contracts available.
  • getSynths({ network }) Return the list of synths for a network
  • getTarget({ network }) Return the information about a contract's address and source file. The contract names are those specified in docs.synthetix.io/addresses
  • getTokens({ network }) Return the list of tokens (synths and SNX) used in the system, along with their addresses.
  • getUsers({ network }) Return the list of user accounts within the Synthetix protocol (e.g. owner, fee, etc)
  • getVersions({ network, byContract = false }) Return the list of deployed versions to the network keyed by tagged version. If byContract is true, it keys by contract name.
  • networks Return the list of supported networks
  • toBytes32 Convert any string to a bytes32 value

Via code

const snx = require('synthetix');

snx.getAST();
/*
{ 'contracts/AddressResolver.sol':
   { imports:
      [ 'contracts/Owned.sol',
        'contracts/interfaces/IAddressResolver.sol',
        'contracts/interfaces/ISynthetix.sol' ],
     contracts: { AddressResolver: [Object] },
     interfaces: {},
     libraries: {} },
  'contracts/Owned.sol':
   { imports: [],
     contracts: { Owned: [Object] },
     interfaces: {},
     libraries: {} },
*/

snx.getAST({ source: 'Synthetix.sol' });
/*
{ imports:
   [ 'contracts/ExternStateToken.sol',
     'contracts/MixinResolver.sol',
     'contracts/interfaces/ISynthetix.sol',
     'contracts/TokenState.sol',
     'contracts/interfaces/ISynth.sol',
     'contracts/interfaces/IERC20.sol',
     'contracts/interfaces/ISystemStatus.sol',
     'contracts/interfaces/IExchanger.sol',
     'contracts/interfaces/IIssuer.sol',
     'contracts/interfaces/ISynthetixState.sol',
     'contracts/interfaces/IExchangeRates.sol',
     'contracts/SupplySchedule.sol',
     'contracts/interfaces/IRewardEscrow.sol',
     'contracts/interfaces/IHasBalance.sol',
     'contracts/interfaces/IRewardsDistribution.sol' ],
  contracts:
   { Synthetix:
      { functions: [Array],
        events: [Array],
        variables: [Array],
        modifiers: [Array],
        structs: [],
        inherits: [Array] } },
  interfaces: {},
  libraries: {} }
*/

// Get the path to the network
snx.getPathToNetwork({ network: 'mainnet' });
//'.../Synthetixio/synthetix/publish/deployed/mainnet'

// retrieve an object detailing the contract ABI and bytecode
snx.getSource({ network: 'goerli', contract: 'Proxy' });
/*
{
  bytecode: '0..0',
  abi: [ ... ]
}
*/

snx.getSuspensionReasons();
/*
{
	1: 'System Upgrade',
	2: 'Market Closure',
	3: 'Circuit breaker',
	99: 'Emergency',
};
*/

// retrieve the array of synths used
snx.getSynths({ network: 'goerli' }).map(({ name }) => name);
// ['sUSD', 'sEUR', ...]

// retrieve an object detailing the contract deployed to the given network.
snx.getTarget({ network: 'goerli', contract: 'ProxySynthetix' });
/*
{
	name: 'ProxySynthetix',
  address: '0x322A3346bf24363f451164d96A5b5cd5A7F4c337',
  source: 'Proxy',
  link: 'https://goerli.etherscan.io/address/0x322A3346bf24363f451164d96A5b5cd5A7F4c337',
  timestamp: '2019-03-06T23:05:43.914Z',
  txn: '',
	network: 'goerli'
}
*/

// retrieve the list of system user addresses
snx.getUsers({ network: 'mainnet' });
/*
[ { name: 'owner',
    address: '0xEb3107117FEAd7de89Cd14D463D340A2E6917769' },
  { name: 'deployer',
    address: '0xEde8a407913A874Dd7e3d5B731AFcA135D30375E' },
  { name: 'marketClosure',
    address: '0xC105Ea57Eb434Fbe44690d7Dec2702e4a2FBFCf7' },
  { name: 'oracle',
    address: '0xaC1ED4Fabbd5204E02950D68b6FC8c446AC95362' },
  { name: 'fee',
    address: '0xfeEFEEfeefEeFeefEEFEEfEeFeefEEFeeFEEFEeF' },
  { name: 'zero',
    address: '0x0000000000000000000000000000000000000000' } ]
*/

snx.getVersions();
/*
{ 'v2.21.12-107':
   { tag: 'v2.21.12-107',
     fulltag: 'v2.21.12-107',
     release: 'Hadar',
     network: 'goerli',
     date: '2020-05-08T12:52:06-04:00',
     commit: '19997724bc7eaceb902c523a6742e0bd74fc75cb',
		 contracts: { ReadProxyAddressResolver: [Object] }
		}
}
*/

snx.networks;
// [ 'local', 'goerli', 'mainnet' ]

snx.toBytes32('sUSD');
// '0x7355534400000000000000000000000000000000000000000000000000000000'

As a CLI tool

Same as above but as a CLI tool that outputs JSON, using names without the get prefixes:

$ npx synthetix ast contracts/Synth.sol
{
  "imports": [
    "contracts/Owned.sol",
    "contracts/ExternStateToken.sol",
    "contracts/MixinResolver.sol",
    "contracts/interfaces/ISynth.sol",
    "contracts/interfaces/IERC20.sol",
    "contracts/interfaces/ISystemStatus.sol",
    "contracts/interfaces/IFeePool.sol",
    "contracts/interfaces/ISynthetix.sol",
    "contracts/interfaces/IExchanger.sol",
    "contracts/interfaces/IIssue"
    # ...
  ]
}

$ npx synthetix bytes32 sUSD
0x7355534400000000000000000000000000000000000000000000000000000000

$ npx synthetix networks
[ 'local', 'goerli', 'mainnet' ]

$ npx synthetix source --network goerli --contract Proxy
{
  "bytecode": "0..0",
  "abi": [ ... ]
}

$ npx synthetix suspension-reason --code 2
Market Closure

$ npx synthetix synths --network goerli --key name
["sUSD", "sEUR", ... ]

$ npx synthetix target --network goerli --contract ProxySynthetix
{
  "name": "ProxySynthetix",
  "address": "0x322A3346bf24363f451164d96A5b5cd5A7F4c337",
  "source": "Proxy",
  "link": "https://goerli.etherscan.io/address/0x322A3346bf24363f451164d96A5b5cd5A7F4c337",
  "timestamp": "2019-03-06T23:05:43.914Z",
  "network": "goerli"
}

$ npx synthetix users --network mainnet --user oracle
{
  "name": "oracle",
  "address": "0xaC1ED4Fabbd5204E02950D68b6FC8c446AC95362"
}

$ npx synthetix versions
{
  "v2.0-19": {
    "tag": "v2.0-19",
    "fulltag": "v2.0-19",
    "release": "",
    "network": "mainnet",
    "date": "2019-03-11T18:17:52-04:00",
    "commit": "eeb271f4fdd2e615f9dba90503f42b2cb9f9716e",
    "contracts": {
      "Depot": {
        "address": "0x172E09691DfBbC035E37c73B62095caa16Ee2388",
        "status": "replaced",
        "replaced_in": "v2.18.1"
      },
      "ExchangeRates": {
        "address": "0x73b172756BD5DDf0110Ba8D7b88816Eb639Eb21c",
        "status": "replaced",
        "replaced_in": "v2.1.11"
      },

      # ...

    }
  }
}

$ npx synthetix versions --by-contract
{
  "Depot": [
    {
      "address": "0x172E09691DfBbC035E37c73B62095caa16Ee2388",
      "status": "replaced",
      "replaced_in": "v2.18.1"
    },
    {
      "address": "0xE1f64079aDa6Ef07b03982Ca34f1dD7152AA3b86",
      "status": "current"
    }
  ],
  "ExchangeRates": [
    {
      "address": "0x73b172756BD5DDf0110Ba8D7b88816Eb639Eb21c",
      "status": "replaced",
      "replaced_in": "v2.1.11"
    },

    # ...
  ],

  # ...
}