├── .circleci ├── config.yml └── test-batch.js ├── .env.sample ├── .github ├── dependabot.yml └── workflows │ └── cannon-update.yml ├── .gitignore ├── .npmrc ├── .prettierignore ├── .prettierrc ├── .solhint.json ├── .solhintignore ├── .yarn └── releases │ ├── yarn-4.6.0.cjs │ └── yarn-4.7.0.cjs ├── .yarnrc.yml ├── LICENSE ├── README.md ├── SECURITY.md ├── auxiliary ├── ArbitrumGasPriceOracle │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── cannonfile.test.toml │ ├── cannonfile.toml │ ├── contracts │ │ ├── ArbGasPriceOracle.sol │ │ └── interfaces │ │ │ └── ArbGasInfo.sol │ ├── foundry.toml │ ├── hardhat.config.ts │ ├── package.json │ ├── remappings.txt │ ├── storage.dump.json │ └── test │ │ └── ArbGasPriceOracle.test.sol ├── BuybackSnx │ ├── .gitignore │ ├── LICENSE │ ├── cannonfile.test.toml │ ├── cannonfile.toml │ ├── contracts │ │ └── BuybackSnx.sol │ ├── hardhat.config.ts │ ├── package.json │ ├── storage.dump.json │ └── test │ │ └── integration │ │ ├── BuybackSnx.test.ts │ │ └── bootstrap.ts ├── ERC4626ToAssetsRatioOracle │ ├── .gitignore │ ├── LICENSE │ ├── cannonfile.test.toml │ ├── cannonfile.toml │ ├── contracts │ │ ├── ERC4626ToAssetsRatioOracle.sol │ │ ├── interfaces │ │ │ ├── IERC20.sol │ │ │ ├── IERC20Metadata.sol │ │ │ └── IERC4626.sol │ │ └── mocks │ │ │ ├── ERC20Mock.sol │ │ │ ├── ERC4626 │ │ │ ├── Math.sol │ │ │ ├── Panic.sol │ │ │ └── SafeCast.sol │ │ │ └── ERC4626Mock.sol │ ├── hardhat.config.ts │ ├── package.json │ ├── storage.dump.json │ └── test │ │ ├── bootstrap.ts │ │ └── integration │ │ └── ERC4626ToAssetsRatioOracle.test.ts ├── OpGasPriceOracle │ ├── .gitignore │ ├── LICENSE │ ├── cannonfile.test.toml │ ├── cannonfile.toml │ ├── contracts │ │ ├── OpGasPriceOracle.sol │ │ └── interfaces │ │ │ ├── IOVM_GasPriceOracle_bedrock.sol │ │ │ ├── IOVM_GasPriceOracle_ecotone.sol │ │ │ └── IOVM_GasPriceOracle_fjord.sol │ ├── foundry.toml │ ├── hardhat.config.ts │ ├── package.json │ ├── remappings.txt │ ├── storage.dump.json │ └── test │ │ └── OpGasPriceOracle.test.sol ├── OwnedFeeCollector │ ├── .gitignore │ ├── LICENSE │ ├── cannonfile.test.toml │ ├── cannonfile.toml │ ├── contracts │ │ └── OwnedFeeCollector.sol │ ├── hardhat.config.ts │ ├── package.json │ └── test │ │ └── integration │ │ ├── OwnedFeeCollector.test.ts │ │ └── bootstrap.ts ├── PythERC7412Wrapper │ ├── .gitignore │ ├── LICENSE │ ├── cannonfile.test.toml │ ├── cannonfile.toml │ ├── contracts │ │ ├── PythERC7412Wrapper.sol │ │ ├── interfaces │ │ │ └── IERC7412.sol │ │ └── storage │ │ │ └── Price.sol │ ├── foundry.toml │ ├── hardhat.config.ts │ ├── package.json │ ├── remappings.txt │ ├── storage.dump.json │ └── test │ │ └── PythERC7412Wrapper.test.sol ├── README.md ├── RewardsDistributor │ ├── .gitignore │ ├── README.md │ ├── cannonfile.snapshot.toml │ ├── cannonfile.toml │ ├── foundry.toml │ ├── package.json │ ├── src │ │ ├── RewardsDistributor.sol │ │ └── SnapshotRewardsDistributor.sol │ └── test │ │ ├── MintableToken.sol │ │ ├── RewardsDistributorConstructorTest.sol │ │ ├── RewardsDistributorPrecisionTest.sol │ │ ├── RewardsDistributorTest.sol │ │ └── SnapshotRewardsDistributorUnitTest.sol ├── RewardsDistributorExternal │ ├── .gitignore │ ├── README.md │ ├── cannonfile.toml │ ├── foundry.toml │ ├── package.json │ ├── src │ │ └── RewardsDistributorExternal.sol │ └── test │ │ ├── MintableToken.sol │ │ ├── RewardsDistributorExternalConstructorTest.sol │ │ └── RewardsDistributorExternalTest.sol ├── SpotMarketOracle │ ├── .gitignore │ ├── LICENSE │ ├── cannonfile.test.toml │ ├── cannonfile.toml │ ├── contracts │ │ ├── SpotMarketOracle.sol │ │ └── interfaces │ │ │ └── ISpotMarketSystem.sol │ ├── hardhat.config.ts │ ├── package.json │ └── storage.dump.json ├── TrustedMulticallForwarder │ ├── .gitignore │ ├── README.md │ ├── cannonfile.clone.toml │ ├── cannonfile.toml │ ├── foundry.toml │ ├── remappings.txt │ ├── src │ │ └── TrustedMulticallForwarder.sol │ └── test │ │ ├── Multicall3.t.sol │ │ ├── TrustedMulticallForwarder.t.sol │ │ └── mocks │ │ ├── EtherSink.sol │ │ └── MockCallee.sol └── WstEthToStEthRatioOracle │ ├── .gitignore │ ├── LICENSE │ ├── cannonfile.test.toml │ ├── cannonfile.toml │ ├── contracts │ ├── WstEthToStEthRatioOracle.sol │ ├── interfaces │ │ └── IWstETH.sol │ └── mocks │ │ ├── AggregatorV3Mock.sol │ │ └── WstETHMock.sol │ ├── hardhat.config.ts │ ├── package.json │ ├── storage.dump.json │ └── test │ ├── bootstrap.ts │ └── integration │ └── LidoWstEthToStEthRatioOracle.test.ts ├── codecov.yml ├── eslint.config.js ├── funding.json ├── lerna.json ├── markets ├── bfp-market │ ├── README.md │ ├── assets │ │ ├── diagram.png │ │ └── overview.png │ ├── cannonfile.test.toml │ ├── cannonfile.toml │ ├── contracts │ │ ├── Proxy.sol │ │ ├── external │ │ │ └── ISynthetixSystem.sol │ │ ├── interfaces │ │ │ ├── IBasePerpMarket.sol │ │ │ ├── IFeatureFlagModule.sol │ │ │ ├── ILiquidationModule.sol │ │ │ ├── IMarginModule.sol │ │ │ ├── IMarketConfigurationModule.sol │ │ │ ├── IOrderModule.sol │ │ │ ├── IPerpAccountModule.sol │ │ │ ├── IPerpMarketFactoryModule.sol │ │ │ ├── IPerpRewardDistributor.sol │ │ │ ├── IPerpRewardDistributorFactoryModule.sol │ │ │ ├── ISettlementHookModule.sol │ │ │ ├── ISplitAccountConfigurationModule.sol │ │ │ └── hooks │ │ │ │ └── ISettlementHook.sol │ │ ├── mocks │ │ │ ├── CollateralMock.sol │ │ │ ├── ExternalMocks.sol │ │ │ ├── MergeAccountSettlementHookMock.sol │ │ │ ├── SettlementHookMock.sol │ │ │ └── modules │ │ │ │ └── __TestHelperModule.sol │ │ ├── modules │ │ │ ├── CoreModule.sol │ │ │ ├── FeatureFlagModule.sol │ │ │ ├── LiquidationModule.sol │ │ │ ├── MarginModule.sol │ │ │ ├── MarketConfigurationModule.sol │ │ │ ├── OrderModule.sol │ │ │ ├── PerpAccountModule.sol │ │ │ ├── PerpMarketFactoryModule.sol │ │ │ ├── PerpRewardDistributorModule │ │ │ │ ├── PerpRewardDistributor.sol │ │ │ │ └── PerpRewardDistributorFactoryModule.sol │ │ │ ├── SettlementHookModule.sol │ │ │ └── SplitAccountConfigurationModule.sol │ │ ├── storage │ │ │ ├── AddressRegistry.sol │ │ │ ├── Margin.sol │ │ │ ├── Order.sol │ │ │ ├── PerpMarket.sol │ │ │ ├── PerpMarketConfiguration.sol │ │ │ ├── Position.sol │ │ │ ├── SettlementHookConfiguration.sol │ │ │ └── SplitAccountConfiguration.sol │ │ └── utils │ │ │ ├── ErrorUtil.sol │ │ │ ├── Flags.sol │ │ │ ├── MathUtil.sol │ │ │ └── PythUtil.sol │ ├── hardhat.config.ts │ ├── package.json │ ├── scripts │ │ └── stable_test.sh │ ├── storage.dump.json │ ├── test │ │ ├── assert.ts │ │ ├── bootstrap.ts │ │ ├── calculations.ts │ │ ├── data │ │ │ └── markets.fixture.ts │ │ ├── generators.ts │ │ ├── helpers.ts │ │ ├── integration │ │ │ ├── __TestHelperModule.test.ts │ │ │ └── modules │ │ │ │ ├── FeatureFlagModule.test.ts │ │ │ │ ├── LiquidationModule.flagPosition.test.ts │ │ │ │ ├── LiquidationModule.getHealthFactor.test.ts │ │ │ │ ├── LiquidationModule.getLiquidationMarginUsd.test.ts │ │ │ │ ├── LiquidationModule.getRemainingLiquidatableSizeCapacity.test.ts │ │ │ │ ├── LiquidationModule.liquidatePostion.test.ts │ │ │ │ ├── LiquidationModule.partialLiquidation.test.ts │ │ │ │ ├── MarginModule.debt.test.ts │ │ │ │ ├── MarginModule.test.ts │ │ │ │ ├── MarketConfigurationModule.test.ts │ │ │ │ ├── OrderModule.cancel.test.ts │ │ │ │ ├── OrderModule.fees.test.ts │ │ │ │ ├── OrderModule.test.ts │ │ │ │ ├── PerpAccountModule.mergeAccounts.test.ts │ │ │ │ ├── PerpAccountModule.splitAccount.test.ts │ │ │ │ ├── PerpAccountModule.test.ts │ │ │ │ ├── PerpMarketFactoryModule.minimumCredit.test.ts │ │ │ │ ├── PerpMarketFactoryModule.test.ts │ │ │ │ ├── PerpMarketFactoryModule.utilisation.test.ts │ │ │ │ ├── PerpRewardDistributor.test.ts │ │ │ │ ├── PerpRewardDistributorFactoryModule.test.ts │ │ │ │ ├── SettlementHookModule.test.ts │ │ │ │ └── SplitAccountConfigurationModule.test.ts │ │ └── typed.ts │ └── tsconfig.json ├── legacy-market │ ├── cannonfile.test.toml │ ├── cannonfile.toml │ ├── contracts │ │ ├── InitialModuleBundle.sol │ │ ├── LegacyMarket.sol │ │ ├── Proxy.sol │ │ ├── SNXDistributor.sol │ │ └── interfaces │ │ │ ├── ILegacyMarket.sol │ │ │ ├── ISNXDistributor.sol │ │ │ └── external │ │ │ ├── IAddressResolver.sol │ │ │ ├── IIssuer.sol │ │ │ ├── ILiquidatorRewards.sol │ │ │ ├── IRewardEscrowV2.sol │ │ │ ├── ISynth.sol │ │ │ ├── ISynthetix.sol │ │ │ ├── ISynthetixDebtShare.sol │ │ │ └── IV3CoreProxy.sol │ ├── hardhat.config.ts │ ├── package.json │ ├── regenerate-external-interfaces.sh │ ├── storage.dump.json │ └── test │ │ ├── integration │ │ ├── LegacyMarket.iosiroInfiniteMoney.ts │ │ └── LegacyMarket.ts │ │ └── utils.ts ├── perps-market │ ├── .gitignore │ ├── .solcover.js │ ├── README.md │ ├── cannonfile.test.toml │ ├── cannonfile.toml │ ├── contracts │ │ ├── .gitignore │ │ ├── Mocks.sol │ │ ├── Proxy.sol │ │ ├── interfaces │ │ │ ├── IAccountEvents.sol │ │ │ ├── IAsyncOrderCancelModule.sol │ │ │ ├── IAsyncOrderModule.sol │ │ │ ├── IAsyncOrderSettlementPythModule.sol │ │ │ ├── ICollateralConfigurationModule.sol │ │ │ ├── IDistributorErrors.sol │ │ │ ├── IGlobalPerpsMarketModule.sol │ │ │ ├── ILiquidationModule.sol │ │ │ ├── IMarketConfigurationModule.sol │ │ │ ├── IMarketEvents.sol │ │ │ ├── IPerpsAccountModule.sol │ │ │ ├── IPerpsMarketFactoryModule.sol │ │ │ ├── IPerpsMarketModule.sol │ │ │ └── external │ │ │ │ ├── IFeeCollector.sol │ │ │ │ ├── IPythERC7412Wrapper.sol │ │ │ │ ├── ISpotMarketSystem.sol │ │ │ │ └── ISynthetixSystem.sol │ │ ├── mocks │ │ │ ├── FeeCollectorMock.sol │ │ │ ├── MockGasPriceNode.sol │ │ │ ├── MockPyth.sol │ │ │ ├── MockPythERC7412Wrapper.sol │ │ │ └── MockRewardsDistributorExternal.sol │ │ ├── modules │ │ │ ├── AssociatedSystemsModule.sol │ │ │ ├── AsyncOrderCancelModule.sol │ │ │ ├── AsyncOrderModule.sol │ │ │ ├── AsyncOrderSettlementPythModule.sol │ │ │ ├── CollateralConfigurationModule.sol │ │ │ ├── CoreModule.sol │ │ │ ├── FeatureFlagModule.sol │ │ │ ├── GlobalPerpsMarketModule.sol │ │ │ ├── LiquidationModule.sol │ │ │ ├── MarketConfigurationModule.sol │ │ │ ├── PerpsAccountModule.sol │ │ │ ├── PerpsMarketFactoryModule.sol │ │ │ └── PerpsMarketModule.sol │ │ ├── storage │ │ │ ├── AsyncOrder.sol │ │ │ ├── GlobalPerpsMarket.sol │ │ │ ├── GlobalPerpsMarketConfiguration.sol │ │ │ ├── InterestRate.sol │ │ │ ├── KeeperCosts.sol │ │ │ ├── Liquidation.sol │ │ │ ├── LiquidationAssetManager.sol │ │ │ ├── MarketUpdate.sol │ │ │ ├── OrderFee.sol │ │ │ ├── PerpsAccount.sol │ │ │ ├── PerpsCollateralConfiguration.sol │ │ │ ├── PerpsMarket.sol │ │ │ ├── PerpsMarketConfiguration.sol │ │ │ ├── PerpsMarketFactory.sol │ │ │ ├── PerpsPrice.sol │ │ │ ├── Position.sol │ │ │ └── SettlementStrategy.sol │ │ └── utils │ │ │ ├── BigNumber.sol │ │ │ ├── Flags.sol │ │ │ └── MathUtil.sol │ ├── hardhat.config.ts │ ├── package.json │ ├── storage.dump.json │ ├── subgraph │ │ ├── .gitignore │ │ ├── base-mainnet-andromeda │ │ │ ├── generated │ │ │ │ ├── PerpsMarketProxy │ │ │ │ │ └── PerpsMarketProxy.ts │ │ │ │ └── schema.ts │ │ │ ├── handleAccountCreated.ts │ │ │ ├── handleCollateralModified.ts │ │ │ ├── handleFundingParametersSet.ts │ │ │ ├── handleLiquidationParametersSet.ts │ │ │ ├── handleLockedOiRatioSet.ts │ │ │ ├── handleMarketCreated.ts │ │ │ ├── handleMarketPriceDataUpdated.ts │ │ │ ├── handleMarketUpdated.ts │ │ │ ├── handleMaxLiquidationParametersSet.ts │ │ │ ├── handleOrderCommitted.ts │ │ │ ├── handleOrderFeesSet.ts │ │ │ ├── handleOrderSettled.ts │ │ │ ├── handlePositionLiquidated.ts │ │ │ ├── handlePreviousOrderExpired.ts │ │ │ ├── handleReferrerShareUpdated.ts │ │ │ ├── handleSettlementStrategyAdded.ts │ │ │ ├── handleSettlementStrategySet.ts │ │ │ ├── index.ts │ │ │ └── schema.graphql │ │ ├── base-sepolia-andromeda │ │ │ ├── generated │ │ │ │ ├── PerpsMarketProxy │ │ │ │ │ └── PerpsMarketProxy.ts │ │ │ │ └── schema.ts │ │ │ ├── index.ts │ │ │ └── schema.graphql │ │ ├── build.sh │ │ ├── codegen.sh │ │ ├── matchstick.yaml │ │ ├── package.json │ │ ├── startBlock.js │ │ ├── subgraph.base-mainnet-andromeda.yaml │ │ ├── subgraph.base-sepolia-andromeda.yaml │ │ ├── tests │ │ │ ├── PerpsMarketProxy.test.ts │ │ │ ├── event-factories │ │ │ │ ├── createAccountCreatedEvent.ts │ │ │ │ ├── createCollateralModifiedEvent.ts │ │ │ │ ├── createFundingParametersSetEvent.ts │ │ │ │ ├── createLiquidationParametersSetEvent.ts │ │ │ │ ├── createLockedOiRatioSetEvent.ts │ │ │ │ ├── createMarketCreatedEvent.ts │ │ │ │ ├── createMarketPriceDataUpdatedEvent.ts │ │ │ │ ├── createMarketUpdatedEvent.ts │ │ │ │ ├── createMaxLiquidationParametersSetEvent.ts │ │ │ │ ├── createOrderCommittedEvent.ts │ │ │ │ ├── createOrderFeesSetEvent.ts │ │ │ │ ├── createOrderSettledEvent.ts │ │ │ │ ├── createPositionLiquidatedEvent.ts │ │ │ │ ├── createPreviousOrderExpiredEvent.ts │ │ │ │ ├── createReferrerShareUpdatedEvent.ts │ │ │ │ ├── createSettlementStrategyAddedEvent.ts │ │ │ │ └── createSettlementStrategySetEvent.ts │ │ │ ├── handleAccountCreated.ts │ │ │ ├── handleCollateralModified.ts │ │ │ ├── handleFundingParametersSet.ts │ │ │ ├── handleLiquidationParametersSet.ts │ │ │ ├── handleLockedOiRatioSet.ts │ │ │ ├── handleMarketCreated.ts │ │ │ ├── handleMarketPriceDataUpdated.ts │ │ │ ├── handleMarketUpdated.ts │ │ │ ├── handleMaxLiquidationParametersSet.ts │ │ │ ├── handleOrderCommitted.ts │ │ │ ├── handleOrderFeesSet.ts │ │ │ ├── handleOrderSettled.ts │ │ │ ├── handlePositionLiquidated.ts │ │ │ ├── handlePreviousOrderExpired.ts │ │ │ ├── handleReferrerShareUpdated.ts │ │ │ ├── handleSettlementStrategyAdded.ts │ │ │ └── handleSettlementStrategySet.ts │ │ └── tsconfig.json │ └── test │ │ └── integration │ │ ├── Account │ │ ├── Debt.test.ts │ │ ├── Margins.multiCollateral.failure.test.ts │ │ ├── Margins.multiCollateral.test.ts │ │ ├── Margins.test.ts │ │ ├── ModifyCollateral.deposit.test.ts │ │ ├── ModifyCollateral.failures.test.ts │ │ ├── ModifyCollateral.withdraw.test.ts │ │ ├── ModifyCollateral.withdrawFull.test.ts │ │ └── PayDebt.test.ts │ │ ├── Insolvent.test.ts │ │ ├── KeeperRewards │ │ ├── KeeperRewards.Caps.test.ts │ │ ├── KeeperRewards.Large-Position.test.ts │ │ ├── KeeperRewards.N-Collaterals.test.ts │ │ ├── KeeperRewards.N-Positions.test.ts │ │ └── KeeperRewards.Settlement.test.ts │ │ ├── Liquidation │ │ ├── Liquidation.flaggedLiquidation.test.ts │ │ ├── Liquidation.margin.test.ts │ │ ├── Liquidation.marginOnly.test.ts │ │ ├── Liquidation.maxLiquidationAmount.endorsedLiquidator.test.ts │ │ ├── Liquidation.maxLiquidationAmount.macro.test.ts │ │ ├── Liquidation.maxLiquidationAmount.maxPd.test.ts │ │ ├── Liquidation.maxLiquidationAmount.test.ts │ │ ├── Liquidation.multi-collateral.test.ts │ │ └── Liquidation.strictStaleness.test.ts │ │ ├── Market │ │ ├── CreateMarket.failures.test.ts │ │ ├── CreateMarket.test.ts │ │ ├── Market.RewardDistributor.test.ts │ │ ├── Market.maxCollateralsPerAccount.test.ts │ │ ├── Market.maxPositionsPerAccount.test.ts │ │ ├── Market.minimumCredit.test.ts │ │ ├── MarketConfiguration.test.ts │ │ ├── MarketDebt.test.ts │ │ ├── MarketDebt.withFunding.test.ts │ │ ├── PerpsMarketModule.test.ts │ │ └── Size.test.ts │ │ ├── Markets │ │ └── GlobalPerpsMarket.test.ts │ │ ├── Orders │ │ ├── LargSizePosition.test.ts │ │ ├── OffchainAsyncOrder.cancel.test.ts │ │ ├── OffchainAsyncOrder.commit.test.ts │ │ ├── OffchainAsyncOrder.fees.test.ts │ │ ├── OffchainAsyncOrder.orderSettledEvent.test.ts │ │ ├── OffchainAsyncOrder.pending.test.ts │ │ ├── OffchainAsyncOrder.price.test.ts │ │ ├── OffchainAsyncOrder.referrer.test.ts │ │ ├── OffchainAsyncOrder.settle.test.ts │ │ ├── OffchainAsyncOrder.zeroFees.test.ts │ │ ├── Order.marginValidation.capped.test.ts │ │ ├── Order.marginValidation.test.ts │ │ ├── Order.marginWithPd.test.ts │ │ ├── Order.marginWithPrice.test.ts │ │ └── Order.reduceSize.test.ts │ │ ├── OrdersFunding.poly.test.ts │ │ ├── Position │ │ ├── Funding.test.ts │ │ ├── InterestRate.reset.test.ts │ │ ├── InterestRate.test.ts │ │ └── InterestRate.tolerance.test.ts │ │ ├── Suspend.test.ts │ │ ├── bootstrap │ │ ├── bootstrap.ts │ │ ├── bootstrapPerpsMarkets.ts │ │ ├── bootstrapTraders.ts │ │ ├── createKeeperCostNode.ts │ │ ├── createRewardsDistributor.ts │ │ └── index.ts │ │ └── helpers │ │ ├── collateralHelper.ts │ │ ├── computeFees.ts │ │ ├── createAccountAndPosition.ts │ │ ├── fillPrice.ts │ │ ├── funding-calcs.ts │ │ ├── index.ts │ │ ├── interestRate.ts │ │ ├── maxSize.ts │ │ ├── openPosition.ts │ │ ├── requiredMargins.ts │ │ └── settleHelper.ts ├── spot-market │ ├── .gitignore │ ├── .solcover.js │ ├── README.md │ ├── cannonfile.test.toml │ ├── cannonfile.toml │ ├── contracts │ │ ├── .gitignore │ │ ├── Mocks.sol │ │ ├── Proxy.sol │ │ ├── interfaces │ │ │ ├── IAsyncOrderConfigurationModule.sol │ │ │ ├── IAsyncOrderModule.sol │ │ │ ├── IAsyncOrderSettlementModule.sol │ │ │ ├── IAtomicOrderModule.sol │ │ │ ├── IMarketConfigurationModule.sol │ │ │ ├── ISpotMarketFactoryModule.sol │ │ │ ├── ISynthTokenModule.sol │ │ │ ├── IWrapperModule.sol │ │ │ └── external │ │ │ │ ├── IAggregatorV3Interface.sol │ │ │ │ ├── IChainlinkVerifier.sol │ │ │ │ ├── IFeeCollector.sol │ │ │ │ ├── IPythERC7412Wrapper.sol │ │ │ │ └── ISynthetixSystem.sol │ │ ├── mocks │ │ │ ├── AggregatorV3Mock.sol │ │ │ ├── CollateralMock.sol │ │ │ ├── ERC20Mock.sol │ │ │ ├── FeeCollectorMock.sol │ │ │ └── MockPythERC7412Wrapper.sol │ │ ├── modules │ │ │ ├── AsyncOrderConfigurationModule.sol │ │ │ ├── AsyncOrderModule.sol │ │ │ ├── AsyncOrderSettlementModule.sol │ │ │ ├── AtomicOrderModule.sol │ │ │ ├── CoreModule.sol │ │ │ ├── FeatureFlagModule.sol │ │ │ ├── MarketConfigurationModule.sol │ │ │ ├── SpotMarketFactoryModule.sol │ │ │ ├── WrapperModule.sol │ │ │ └── token │ │ │ │ └── SynthTokenModule.sol │ │ ├── storage │ │ │ ├── AsyncOrder.sol │ │ │ ├── AsyncOrderClaim.sol │ │ │ ├── AsyncOrderConfiguration.sol │ │ │ ├── MarketConfiguration.sol │ │ │ ├── OrderFees.sol │ │ │ ├── Price.sol │ │ │ ├── SettlementStrategy.sol │ │ │ ├── SpotMarketFactory.sol │ │ │ └── Wrapper.sol │ │ └── utils │ │ │ ├── Flags.sol │ │ │ ├── MathUtil.sol │ │ │ ├── SynthUtil.sol │ │ │ └── TransactionUtil.sol │ ├── hardhat.config.ts │ ├── package.json │ ├── storage.dump.json │ ├── subgraph │ │ ├── .gitignore │ │ ├── base-mainnet-andromeda │ │ │ ├── generated │ │ │ │ ├── SpotMarketProxy │ │ │ │ │ └── SpotMarketProxy.ts │ │ │ │ └── schema.ts │ │ │ ├── index.ts │ │ │ └── schema.graphql │ │ ├── base-sepolia-andromeda │ │ │ ├── generated │ │ │ │ ├── SpotMarketProxy │ │ │ │ │ └── SpotMarketProxy.ts │ │ │ │ └── schema.ts │ │ │ ├── index.ts │ │ │ └── schema.graphql │ │ ├── build.sh │ │ ├── codegen.sh │ │ ├── matchstick.yaml │ │ ├── optimism-mainnet │ │ │ ├── generated │ │ │ │ ├── SpotMarketProxy │ │ │ │ │ └── SpotMarketProxy.ts │ │ │ │ └── schema.ts │ │ │ ├── handleOrderCancelled.ts │ │ │ ├── handleOrderCommitted.ts │ │ │ ├── handleOrderSettled.ts │ │ │ ├── handleSettlementStrategyAdded.ts │ │ │ ├── handleSettlementStrategySet.ts │ │ │ ├── handleSynthPriceDataUpdated.ts │ │ │ ├── handleSynthUnwrapped.ts │ │ │ ├── handleSynthWrapped.ts │ │ │ ├── handleWrapperSet.ts │ │ │ ├── index.ts │ │ │ └── schema.graphql │ │ ├── package.json │ │ ├── startBlock.js │ │ ├── subgraph.base-mainnet-andromeda.yaml │ │ ├── subgraph.base-sepolia-andromeda.yaml │ │ ├── subgraph.optimism-mainnet.yaml │ │ ├── tests │ │ │ ├── SpotMarketProxy.test.ts │ │ │ ├── event-factories │ │ │ │ ├── createOrderCancelledEvent.ts │ │ │ │ ├── createOrderCommittedEvent.ts │ │ │ │ ├── createOrderSettledEvent.ts │ │ │ │ ├── createSettlementStrategyAddedEvent.ts │ │ │ │ ├── createSettlementStrategySetEvent.ts │ │ │ │ ├── createSynthPriceDataUpdatedEvent.ts │ │ │ │ ├── createSynthUnwrappedEvent.ts │ │ │ │ ├── createSynthWrappedEvent.ts │ │ │ │ └── createWrapperSetEvent.ts │ │ │ ├── handleOrderCancelled.ts │ │ │ ├── handleOrderCommitted.ts │ │ │ ├── handleOrderSettled.ts │ │ │ ├── handleSettlementStrategyAdded.ts │ │ │ ├── handleSettlementStrategySet.ts │ │ │ ├── handleSynthPriceDataUpdated.ts │ │ │ ├── handleSynthUnwrapped.ts │ │ │ ├── handleSynthWrapped.ts │ │ │ └── handleWrapperSet.ts │ │ └── tsconfig.json │ ├── test-fork │ │ └── AsyncOrdersModule.e2e.test.ts │ └── test │ │ ├── AsyncOrderConfigurationModule.test.ts │ │ ├── AsyncOrderModule.escrow.test.ts │ │ ├── AsyncOrderModule.onchain.test.ts │ │ ├── AsyncOrderModule.pyth.test.ts │ │ ├── AsyncOrderModule.test.ts │ │ ├── AtomicOrderModule.buy.test.ts │ │ ├── AtomicOrderModule.referrer.test.ts │ │ ├── AtomicOrderModule.sell.test.ts │ │ ├── AtomicOrderModule.utilization.test.ts │ │ ├── SpotMarketFactory.test.ts │ │ ├── WrapperModule.test.ts │ │ ├── bootstrap.ts │ │ ├── common │ │ ├── bootstrapSynthMarkets.ts │ │ └── index.ts │ │ └── integration │ │ ├── Orders.skew.balance.test.ts │ │ └── Orders.skew.test.ts └── treasury-market │ ├── cannonfile.test.toml │ ├── cannonfile.toml │ ├── contracts │ ├── InitialModuleBundle.sol │ ├── SynthetixTreasuryProxy.sol │ ├── TreasuryMarket.sol │ ├── TreasuryStakingRewards.sol │ └── interfaces │ │ ├── ITreasuryMarket.sol │ │ ├── ITreasuryStakingRewards.sol │ │ └── external │ │ ├── IOracleManagerProxy.sol │ │ └── IV3CoreProxy.sol │ ├── foundry.toml │ ├── hardhat.config.ts │ ├── package.json │ ├── remappings.txt │ ├── script │ ├── Deploy.sol │ └── RestorePosition.sol │ ├── storage.dump.json │ └── test │ ├── TreasuryMarket.test.sol │ └── TreasuryStakingRewards.test.sol ├── package.json ├── protocol ├── governance │ ├── .gitignore │ ├── .npmrc │ ├── .solcover.js │ ├── LICENSE │ ├── README.md │ ├── cannonfile.satellite.test.toml │ ├── cannonfile.satellite.toml │ ├── cannonfile.snapshot-record-mock.toml │ ├── cannonfile.test.toml │ ├── cannonfile.toml │ ├── contracts │ │ ├── Proxy.sol │ │ ├── interfaces │ │ │ ├── ICouncilTokenModule.sol │ │ │ ├── IDebtShare.sol │ │ │ ├── IElectionInspectorModule.sol │ │ │ ├── IElectionModule.sol │ │ │ ├── IElectionModuleSatellite.sol │ │ │ ├── ISnapshotVotePowerModule.sol │ │ │ ├── ISynthetixElectionModule.sol │ │ │ └── external │ │ │ │ └── ISnapshotRecord.sol │ │ ├── mocks │ │ │ ├── CouncilMemberMock.sol │ │ │ ├── DebtShareMock.sol │ │ │ ├── SnapshotRecordMock.sol │ │ │ ├── WormholeMock.sol │ │ │ └── WormholeRelayerMock.sol │ │ ├── modules │ │ │ ├── core │ │ │ │ ├── AssociatedSystemsModule.sol │ │ │ │ ├── ElectionInspectorModule.sol │ │ │ │ ├── ElectionModule.sol │ │ │ │ ├── ElectionModuleSatellite.sol │ │ │ │ ├── InitialModuleBundle.sol │ │ │ │ ├── SnapshotVotePowerModule.sol │ │ │ │ └── WormholeCrossChainModule.sol │ │ │ └── council-nft │ │ │ │ └── CouncilTokenModule.sol │ │ ├── storage │ │ │ ├── Ballot.sol │ │ │ ├── Council.sol │ │ │ ├── CouncilMembers.sol │ │ │ ├── CrossChainDebtShare.sol │ │ │ ├── Election.sol │ │ │ ├── ElectionSettings.sol │ │ │ ├── Epoch.sol │ │ │ ├── SnapshotVotePower.sol │ │ │ └── SnapshotVotePowerEpoch.sol │ │ ├── submodules │ │ │ └── election │ │ │ │ ├── ElectionCredentials.sol │ │ │ │ └── ElectionTally.sol │ │ └── utils │ │ │ └── MathUtil.sol │ ├── hardhat.config.ts │ ├── package.json │ ├── storage.dump.json │ ├── tasks │ │ └── dev.ts │ ├── test │ │ ├── constants.ts │ │ ├── contracts │ │ │ ├── CouncilTokenModule.test.ts │ │ │ ├── ElectionModule │ │ │ │ ├── CouncilMembers.test.ts │ │ │ │ ├── Initialization.test.ts │ │ │ │ ├── Schedule.test.ts │ │ │ │ └── Voting.test.ts │ │ │ ├── ElectionSchedule.test.ts │ │ │ ├── ElectionSettings.test.ts │ │ │ ├── SnapshotVotePowerModule.test.ts │ │ │ └── bootstrap.ts │ │ ├── helpers │ │ │ ├── debt-share-helper.ts │ │ │ ├── object.ts │ │ │ └── spin-chain.ts │ │ └── integration │ │ │ ├── CrossChainElections.test.ts │ │ │ ├── CrossChainNFTDistribution.test.ts │ │ │ ├── Elections.test.ts │ │ │ ├── Evaluation.test.ts │ │ │ └── bootstrap.ts │ └── tomls │ │ ├── council-token.toml │ │ ├── proxy-base.toml │ │ └── testable-contracts.toml ├── oracle-manager │ ├── .gitignore │ ├── .solcover.js │ ├── LICENSE │ ├── README.md │ ├── cannonfile.test.toml │ ├── cannonfile.toml │ ├── contracts │ │ ├── Dependencies.sol │ │ ├── Proxy.sol │ │ ├── interfaces │ │ │ ├── INodeModule.sol │ │ │ └── external │ │ │ │ ├── IAggregatorV3Interface.sol │ │ │ │ ├── IExternalNode.sol │ │ │ │ ├── IPyth.sol │ │ │ │ └── IUniswapV3Pool.sol │ │ ├── mocks │ │ │ ├── ERC20Mock.sol │ │ │ ├── MockChainlinkAggregator.sol │ │ │ ├── MockExternalNode.sol │ │ │ ├── MockObservable.sol │ │ │ ├── MockPythExternalNode.sol │ │ │ ├── MockV3Aggregator.sol │ │ │ └── pyth │ │ │ │ ├── AbstractPyth.sol │ │ │ │ ├── IPythEvents.sol │ │ │ │ ├── IPythMock.sol │ │ │ │ ├── MockPyth.sol │ │ │ │ ├── PythErrors.sol │ │ │ │ └── PythStructs.sol │ │ ├── modules │ │ │ ├── CoreModule.sol │ │ │ └── NodeModule.sol │ │ ├── nodes │ │ │ ├── ChainlinkNode.sol │ │ │ ├── ConstantNode.sol │ │ │ ├── ExternalNode.sol │ │ │ ├── PriceDeviationCircuitBreakerNode.sol │ │ │ ├── ReducerNode.sol │ │ │ ├── StalenessCircuitBreakerNode.sol │ │ │ ├── UniswapNode.sol │ │ │ └── pyth │ │ │ │ ├── PythNode.sol │ │ │ │ └── PythOffchainLookupNode.sol │ │ ├── storage │ │ │ ├── NodeDefinition.sol │ │ │ └── NodeOutput.sol │ │ └── utils │ │ │ ├── FullMath.sol │ │ │ └── TickMath.sol │ ├── hardhat.config.ts │ ├── package.json │ ├── storage.dump.json │ └── test │ │ ├── common │ │ ├── index.ts │ │ └── oracleNode.ts │ │ └── integration │ │ ├── bootstrap.ts │ │ ├── mixins │ │ ├── Node.operations.ts │ │ └── Node.types.ts │ │ ├── modules │ │ └── NodeModule.test.ts │ │ └── nodes │ │ ├── ChainlinkNode.test.ts │ │ ├── ConstantNode.test.ts │ │ ├── ExternalNode.test.ts │ │ ├── PriceDeviationCircuitBreakerNode.test.ts │ │ ├── PythNode.test.ts │ │ ├── PythOffchainLookupNode.test.ts │ │ ├── ReducerNode.test.ts │ │ ├── StalenessCircuitBreakerNode.OffchainLookup.test.ts │ │ ├── StalenessCircuitBreakerNode.test.ts │ │ └── UniswapNode.test.ts └── synthetix │ ├── .gitignore │ ├── .solcover.js │ ├── LICENSE │ ├── cannonfile.common.toml │ ├── cannonfile.test.toml │ ├── cannonfile.toml │ ├── contracts │ ├── Proxy.sol │ ├── interfaces │ │ ├── IAccountModule.sol │ │ ├── IAccountTokenModule.sol │ │ ├── IAssociateDebtModule.sol │ │ ├── ICollateralConfigurationModule.sol │ │ ├── ICollateralModule.sol │ │ ├── ICrossChainUSDModule.sol │ │ ├── IIssueUSDModule.sol │ │ ├── ILiquidationModule.sol │ │ ├── IMarketCollateralModule.sol │ │ ├── IMarketManagerModule.sol │ │ ├── IPoolConfigurationModule.sol │ │ ├── IPoolModule.sol │ │ ├── IRewardsManagerModule.sol │ │ ├── IUSDTokenModule.sol │ │ ├── IUtilsModule.sol │ │ ├── IVaultModule.sol │ │ └── external │ │ │ ├── IAggregatorV3Interface.sol │ │ │ ├── IAny2EVMMessageReceiver.sol │ │ │ ├── ICcipRouterClient.sol │ │ │ ├── IMarket.sol │ │ │ ├── IOracleManager.sol │ │ │ └── IRewardDistributor.sol │ ├── mocks │ │ ├── AggregatorV3Mock.sol │ │ ├── CcipRouterMock.sol │ │ ├── CollateralMock.sol │ │ ├── CollateralMockWithoutDecimals.sol │ │ ├── MockMarket.sol │ │ └── RewardDistributorMock.sol │ ├── modules │ │ ├── InitialModuleBundle.sol │ │ ├── account │ │ │ └── AccountTokenModule.sol │ │ ├── associated-systems │ │ │ └── AssociatedSystemsModule.sol │ │ ├── common │ │ │ ├── OwnerModule.sol │ │ │ └── UpgradeModule.sol │ │ ├── core │ │ │ ├── AccountModule.sol │ │ │ ├── AssociateDebtModule.sol │ │ │ ├── CcipReceiverModule.sol │ │ │ ├── CollateralConfigurationModule.sol │ │ │ ├── CollateralModule.sol │ │ │ ├── CrossChainUSDModule.sol │ │ │ ├── FeatureFlagModule.sol │ │ │ ├── IssueUSDModule.sol │ │ │ ├── LiquidationModule.sol │ │ │ ├── MarketCollateralModule.sol │ │ │ ├── MarketManagerModule.sol │ │ │ ├── PoolConfigurationModule.sol │ │ │ ├── PoolModule.sol │ │ │ ├── RewardsManagerModule.sol │ │ │ ├── UtilsModule.sol │ │ │ └── VaultModule.sol │ │ └── usd │ │ │ └── USDTokenModule.sol │ ├── storage │ │ ├── Account.sol │ │ ├── AccountRBAC.sol │ │ ├── Collateral.sol │ │ ├── CollateralConfiguration.sol │ │ ├── CollateralLock.sol │ │ ├── Config.sol │ │ ├── CrossChain.sol │ │ ├── Distribution.sol │ │ ├── DistributionActor.sol │ │ ├── Market.sol │ │ ├── MarketConfiguration.sol │ │ ├── MarketCreator.sol │ │ ├── MarketPoolInfo.sol │ │ ├── OracleManager.sol │ │ ├── Pool.sol │ │ ├── PoolCollateralConfiguration.sol │ │ ├── RewardDistribution.sol │ │ ├── RewardDistributionClaimStatus.sol │ │ ├── ScalableMapping.sol │ │ ├── SystemAccountConfiguration.sol │ │ ├── SystemPoolConfiguration.sol │ │ ├── Vault.sol │ │ └── VaultEpoch.sol │ └── utils │ │ └── CcipClient.sol │ ├── hardhat.config.ts │ ├── package.json │ ├── storage.dump.json │ ├── subgraph │ ├── .gitignore │ ├── README.md │ ├── arbitrum-mainnet │ │ ├── generated │ │ │ ├── CoreProxy │ │ │ │ └── CoreProxy.ts │ │ │ └── schema.ts │ │ ├── index.ts │ │ └── schema.graphql │ ├── arbitrum-sepolia │ │ ├── generated │ │ │ ├── CoreProxy │ │ │ │ └── CoreProxy.ts │ │ │ └── schema.ts │ │ ├── index.ts │ │ └── schema.graphql │ ├── base-mainnet-andromeda │ │ ├── generated │ │ │ ├── CoreProxy │ │ │ │ └── CoreProxy.ts │ │ │ └── schema.ts │ │ ├── index.ts │ │ └── schema.graphql │ ├── base-sepolia-andromeda │ │ ├── generated │ │ │ ├── CoreProxy │ │ │ │ └── CoreProxy.ts │ │ │ └── schema.ts │ │ ├── index.ts │ │ └── schema.graphql │ ├── build.sh │ ├── codegen.sh │ ├── mainnet │ │ ├── generated │ │ │ ├── CoreProxy │ │ │ │ └── CoreProxy.ts │ │ │ └── schema.ts │ │ ├── getISOWeekNumber.ts │ │ ├── handleAccountCreated.ts │ │ ├── handleCollateralConfigured.ts │ │ ├── handleCollateralDeposited.ts │ │ ├── handleCollateralWithdrawn.ts │ │ ├── handleDelegationUpdated.ts │ │ ├── handleLiquidation.ts │ │ ├── handleMarketCreated.ts │ │ ├── handleMarketUsdDeposited.ts │ │ ├── handleMarketUsdWithdrawn.ts │ │ ├── handlePermissionGranted.ts │ │ ├── handlePermissionRevoked.ts │ │ ├── handlePoolConfigurationSet.ts │ │ ├── handlePoolCreated.ts │ │ ├── handlePoolNameUpdated.ts │ │ ├── handlePoolNominationRenounced.ts │ │ ├── handlePoolNominationRevoked.ts │ │ ├── handlePoolOwnerNominated.ts │ │ ├── handlePoolOwnershipAccepted.ts │ │ ├── handleRewardsClaimed.ts │ │ ├── handleRewardsDistributed.ts │ │ ├── handleRewardsDistributorRegistered.ts │ │ ├── handleRewardsDistributorRemoved.ts │ │ ├── handleUSDBurned.ts │ │ ├── handleUSDMinted.ts │ │ ├── handleVaultLiquidation.ts │ │ ├── index.ts │ │ ├── marketSnapshotByDay.ts │ │ ├── marketSnapshotByWeek.ts │ │ ├── schema.graphql │ │ ├── vaultSnapshotByDay.ts │ │ ├── vaultSnapshotByMonth.ts │ │ ├── vaultSnapshotByWeek.ts │ │ └── vaultSnapshotByYear.ts │ ├── matchstick.yaml │ ├── optimism-mainnet │ │ ├── generated │ │ │ ├── CoreProxy │ │ │ │ └── CoreProxy.ts │ │ │ └── schema.ts │ │ ├── index.ts │ │ └── schema.graphql │ ├── optimism-sepolia │ │ ├── generated │ │ │ ├── CoreProxy │ │ │ │ └── CoreProxy.ts │ │ │ └── schema.ts │ │ ├── index.ts │ │ └── schema.graphql │ ├── package.json │ ├── sepolia │ │ ├── generated │ │ │ ├── CoreProxy │ │ │ │ └── CoreProxy.ts │ │ │ └── schema.ts │ │ ├── index.ts │ │ └── schema.graphql │ ├── startBlock.js │ ├── subgraph.arbitrum-mainnet.yaml │ ├── subgraph.arbitrum-sepolia.yaml │ ├── subgraph.base-mainnet-andromeda.yaml │ ├── subgraph.base-sepolia-andromeda.yaml │ ├── subgraph.mainnet.yaml │ ├── subgraph.optimism-mainnet.yaml │ ├── subgraph.optimism-sepolia.yaml │ ├── subgraph.sepolia.yaml │ ├── tests │ │ ├── CoreProxy.test.ts │ │ ├── constants.ts │ │ ├── event-factories │ │ │ ├── createAccountCreatedEvent.ts │ │ │ ├── createCollateralConfiguredEvent.ts │ │ │ ├── createDelegationUpdatedEvent.ts │ │ │ ├── createDepositEvent.ts │ │ │ ├── createLiquidationEvent.ts │ │ │ ├── createMarketRegisteredEvent.ts │ │ │ ├── createMarketUSDDepositedEvent.ts │ │ │ ├── createMarketUSDWithdrawnEvent.ts │ │ │ ├── createPermissionGrantedEvent.ts │ │ │ ├── createPermissionRevokedEvent.ts │ │ │ ├── createPoolConfigurationSetEvent.ts │ │ │ ├── createPoolCreatedEvent.ts │ │ │ ├── createPoolNameUpdatedEvent.ts │ │ │ ├── createPoolNominationRevokedEvent.ts │ │ │ ├── createPoolOwnerNominatedEvent.ts │ │ │ ├── createPoolOwnershipAcceptedEvent.ts │ │ │ ├── createPoolOwnershipRenouncedEvent.ts │ │ │ ├── createRewardDistributorRegisteredEvent.ts │ │ │ ├── createRewardsClaimedEvent.ts │ │ │ ├── createRewardsDistributedEvent.ts │ │ │ ├── createRewardsDistributorRemovedEvent.ts │ │ │ ├── createUSDBurnedEvent.ts │ │ │ ├── createUSDMintedEvent.ts │ │ │ ├── createVaultLiquidationEvent.ts │ │ │ ├── createWithdrawEvent.ts │ │ │ ├── index.ts │ │ │ └── utils.ts │ │ ├── getISOWeekNumber.ts │ │ ├── handleAccountCreated.ts │ │ ├── handleCollateralConfigured.ts │ │ ├── handleCollateralDeposit.ts │ │ ├── handleCollateralWithdrawn.ts │ │ ├── handleDelegationUpdated.ts │ │ ├── handleLiquidation.ts │ │ ├── handleMarketCreated.ts │ │ ├── handleMarketDeposits.ts │ │ ├── handleMarketWithdrawals.ts │ │ ├── handleNominatedPoolOwner.ts │ │ ├── handlePermissionGranted.ts │ │ ├── handlePermissionRevoked.ts │ │ ├── handlePoolConfigurationSet.ts │ │ ├── handlePoolCreated.ts │ │ ├── handlePoolNameUpdated.ts │ │ ├── handlePoolNominationRenounced.ts │ │ ├── handlePoolNominationRevoked.ts │ │ ├── handlePoolOwnershipAccepted.ts │ │ ├── handleRewardsClaimed.ts │ │ ├── handleRewardsDistributed.ts │ │ ├── handleUSDBurned.ts │ │ ├── handleUSDMinted.ts │ │ ├── handleVaultLiquidation.ts │ │ ├── marketSnapshotByDay.ts │ │ ├── marketSnapshotByWeek.ts │ │ ├── vaultSnapshotByDay.ts │ │ ├── vaultSnapshotByMonth.ts │ │ ├── vaultSnapshotByWeek.ts │ │ └── vaultSnapshotByYear.ts │ └── tsconfig.json │ └── test │ ├── common │ ├── index.ts │ ├── stakedPool.ts │ └── stakers.ts │ └── integration │ ├── bootstrap.ts │ ├── mixins │ └── AccountRBACMixin.permissions.ts │ ├── modules │ └── core │ │ ├── AccountModule │ │ ├── AccountModule.create.test.ts │ │ ├── AccountModule.grant.test.ts │ │ ├── AccountModule.init.test.ts │ │ ├── AccountModule.transfer.test.ts │ │ └── AccountTokenModule.mint.test.ts │ │ ├── AssociateDebtModule.test.ts │ │ ├── CcipReceiverModule.test.ts │ │ ├── CollateralConfigurationModule │ │ └── CollateralConfigurationModule.config.test.ts │ │ ├── CollateralModule │ │ ├── CollateralModule.access.test.ts │ │ ├── CollateralModule.deposit.test.ts │ │ ├── CollateralModule.helper.ts │ │ └── CollateralModule.locks.test.ts │ │ ├── CrossChainUSDModule.test.ts │ │ ├── IssueUSDModule.test.ts │ │ ├── LiquidationModule.test.ts │ │ ├── MarketCollateralModule │ │ └── MarketCollateralModule.test.ts │ │ ├── MarketManagerModule.test.ts │ │ ├── PoolConfigurationModule │ │ └── PoolConfigurationModule.test.ts │ │ ├── PoolModuleFundAdmin.test.ts │ │ ├── PoolModuleOwnership.test.ts │ │ ├── RewardsManagerModule.test.ts │ │ ├── USDTokenModule.test.ts │ │ ├── UtilsModule.test.ts │ │ └── VaultModule.test.ts │ ├── storage │ ├── AccountLocks.test.ts │ ├── AccountRBAC.test.ts │ ├── CollateralConfiguration.test.ts │ ├── Distribution.test.ts │ ├── Market │ │ ├── BumpPools.test.ts │ │ └── Market.test.ts │ ├── Pool.test.ts │ └── ScalableMapping.test.ts │ └── verifications.ts ├── tsconfig.eslint.json ├── tsconfig.json ├── utils ├── common-config │ ├── .solcover.js │ ├── LICENSE │ ├── hardhat.config.ts │ └── package.json ├── core-contracts │ ├── .solcover.js │ ├── LICENSE │ ├── contracts │ │ ├── errors │ │ │ ├── AccessError.sol │ │ │ ├── AddressError.sol │ │ │ ├── ArrayError.sol │ │ │ ├── ChangeError.sol │ │ │ ├── InitError.sol │ │ │ └── ParameterError.sol │ │ ├── initializable │ │ │ └── InitializableMixin.sol │ │ ├── interfaces │ │ │ ├── IConfigurable.sol │ │ │ ├── IERC165.sol │ │ │ ├── IERC20.sol │ │ │ ├── IERC20Permit.sol │ │ │ ├── IERC721.sol │ │ │ ├── IERC721Enumerable.sol │ │ │ ├── IERC721Metadata.sol │ │ │ ├── IERC721Receiver.sol │ │ │ ├── IOwnable.sol │ │ │ └── IUUPSImplementation.sol │ │ ├── mocks │ │ │ ├── initializable │ │ │ │ └── InitializableMock.sol │ │ │ ├── proxy │ │ │ │ ├── ImplementationDestroyer.sol │ │ │ │ ├── ImplementationMockA.sol │ │ │ │ ├── ImplementationMockB.sol │ │ │ │ ├── SterileImplementation.sol │ │ │ │ └── UUPSImplementationMock.sol │ │ │ ├── token │ │ │ │ ├── ERC20Mock.sol │ │ │ │ ├── ERC20PermitMock.sol │ │ │ │ ├── ERC721EnumerableMock.sol │ │ │ │ ├── ERC721FailedReceiverMock.sol │ │ │ │ ├── ERC721Mock.sol │ │ │ │ ├── ERC721OwnedMock.sol │ │ │ │ ├── ERC721ReceiverMock.sol │ │ │ │ ├── ERC721RevertingReceiverMock.sol │ │ │ │ └── VaultMock.sol │ │ │ └── utils │ │ │ │ ├── AddressUtilMock.sol │ │ │ │ ├── ConfigurableMock.sol │ │ │ │ ├── DecimalMathMock.sol │ │ │ │ ├── ERC165HelperMock.sol │ │ │ │ ├── HeapUtilMock.sol │ │ │ │ ├── MerkleProofMock.sol │ │ │ │ ├── RevertUtilMock.sol │ │ │ │ ├── SafeCastMock.sol │ │ │ │ ├── SetUtilMock.sol │ │ │ │ └── StringUtilMock.sol │ │ ├── ownership │ │ │ ├── AuthorizableStorage.sol │ │ │ ├── Configurable.sol │ │ │ ├── ConfigurableStorage.sol │ │ │ ├── Ownable.sol │ │ │ └── OwnableStorage.sol │ │ ├── proxy │ │ │ ├── AbstractProxy.sol │ │ │ ├── ProxyStorage.sol │ │ │ ├── UUPSImplementation.sol │ │ │ ├── UUPSProxy.sol │ │ │ └── UUPSProxyWithOwner.sol │ │ ├── token │ │ │ ├── ERC20.sol │ │ │ ├── ERC20Helper.sol │ │ │ ├── ERC20Permit.sol │ │ │ ├── ERC20PermitStorage.sol │ │ │ ├── ERC20Storage.sol │ │ │ ├── ERC721.sol │ │ │ ├── ERC721Enumerable.sol │ │ │ ├── ERC721EnumerableStorage.sol │ │ │ ├── ERC721Owned.sol │ │ │ └── ERC721Storage.sol │ │ └── utils │ │ │ ├── AddressUtil.sol │ │ │ ├── DecimalMath.sol │ │ │ ├── ERC165Helper.sol │ │ │ ├── ERC2771Context.sol │ │ │ ├── ForkDetector.sol │ │ │ ├── HeapUtil.sol │ │ │ ├── MerkleProof.sol │ │ │ ├── RevertUtil.sol │ │ │ ├── SafeCast.sol │ │ │ ├── SafeCast │ │ │ ├── SafeCastAddress.sol │ │ │ ├── SafeCastBytes32.sol │ │ │ ├── SafeCastI128.sol │ │ │ ├── SafeCastI24.sol │ │ │ ├── SafeCastI256.sol │ │ │ ├── SafeCastI32.sol │ │ │ ├── SafeCastI56.sol │ │ │ ├── SafeCastI64.sol │ │ │ ├── SafeCastU128.sol │ │ │ ├── SafeCastU160.sol │ │ │ ├── SafeCastU256.sol │ │ │ ├── SafeCastU32.sol │ │ │ ├── SafeCastU56.sol │ │ │ └── SafeCastU64.sol │ │ │ ├── SetUtil.sol │ │ │ └── StringUtil.sol │ ├── hardhat.config.ts │ ├── package.json │ └── test │ │ └── contracts │ │ ├── initializable │ │ └── Initializable.test.ts │ │ ├── ownership │ │ ├── Configurable.test.ts │ │ └── Ownable.test.ts │ │ ├── proxy │ │ └── UUPSProxy.test.ts │ │ ├── token │ │ ├── ERC20.test.ts │ │ ├── ERC20Permit.test.ts │ │ ├── ERC721.test.ts │ │ ├── ERC721Enumerable.test.ts │ │ └── ERC721Owned.test.ts │ │ └── utils │ │ ├── AddressUtil.test.ts │ │ ├── DecimalMath.test.ts │ │ ├── ERC165Helper.test.ts │ │ ├── HeapUtil.test.ts │ │ ├── MerkleProof.test.ts │ │ ├── RevertUtil.test.ts │ │ ├── SafeCast.test.ts │ │ ├── SetUtil.test.ts │ │ └── StringUtil.test.ts ├── core-modules │ ├── .gitignore │ ├── .solcover.js │ ├── LICENSE │ ├── cannonfile.test.toml │ ├── cannonfile.toml │ ├── contracts │ │ ├── Proxy.sol │ │ ├── interfaces │ │ │ ├── IAssociatedSystemsModule.sol │ │ │ ├── IDecayTokenModule.sol │ │ │ ├── IFeatureFlagModule.sol │ │ │ ├── INftModule.sol │ │ │ ├── IOwnerModule.sol │ │ │ ├── ISampleFeatureFlagModule.sol │ │ │ ├── ISampleOwnedModule.sol │ │ │ ├── ITokenModule.sol │ │ │ ├── IWormhole.sol │ │ │ ├── IWormholeReceiver.sol │ │ │ ├── IWormholeRelayer.sol │ │ │ └── external │ │ │ │ ├── IAny2EVMMessageReceiver.sol │ │ │ │ └── ICcipRouterClient.sol │ │ ├── mocks │ │ │ ├── CcipRouterMock.sol │ │ │ ├── WormholeMock.sol │ │ │ └── WormholeRelayerMock.sol │ │ ├── modules │ │ │ ├── AssociatedSystemsModule.sol │ │ │ ├── CcipReceiverModule.sol │ │ │ ├── CoreModule.sol │ │ │ ├── DecayTokenModule.sol │ │ │ ├── FeatureFlagModule.sol │ │ │ ├── NftModule.sol │ │ │ ├── OwnerModule.sol │ │ │ ├── TokenModule.sol │ │ │ ├── UpgradeModule.sol │ │ │ ├── WormholeCrossChainModule.sol │ │ │ └── mocks │ │ │ │ ├── GenericModule.sol │ │ │ │ ├── SampleFeatureFlagModule.sol │ │ │ │ └── SampleOwnedModule.sol │ │ ├── storage │ │ │ ├── AssociatedSystem.sol │ │ │ ├── CrossChain.sol │ │ │ ├── DecayToken.sol │ │ │ ├── FeatureFlag.sol │ │ │ ├── Initialized.sol │ │ │ ├── SampleStorage.sol │ │ │ └── WormholeCrossChain.sol │ │ └── utils │ │ │ └── CcipClient.sol │ ├── hardhat.config.ts │ ├── package.json │ ├── storage.dump.json │ └── test │ │ ├── bootstrap.ts │ │ └── contracts │ │ └── modules │ │ ├── AssociatedSystemsModule.test.ts │ │ ├── DecayTokenModule.test.ts │ │ ├── Ether.test.ts │ │ ├── FeatureFlagModule.test.ts │ │ ├── NftModule.test.ts │ │ ├── OwnerModule.test.ts │ │ ├── RouterCoverage.test.ts │ │ ├── TokenModule.test.ts │ │ └── UpgradeModule.test.ts ├── core-utils │ ├── .gitignore │ ├── .mocharc.json │ ├── .nycrc.json │ ├── LICENSE │ ├── package.json │ ├── src │ │ ├── globals.d.ts │ │ ├── tsconfig.json │ │ ├── types.d.ts │ │ └── utils │ │ │ ├── assertions │ │ │ ├── assert-address.ts │ │ │ ├── assert-bignumber.ts │ │ │ ├── assert-event.ts │ │ │ └── assert-revert.ts │ │ │ ├── ast │ │ │ ├── comparator.ts │ │ │ ├── finders.ts │ │ │ └── storage-struct.ts │ │ │ ├── bootstrap │ │ │ ├── cannon-build.ts │ │ │ ├── cannon-node.ts │ │ │ ├── cannon-types.ts │ │ │ ├── get-hardhat-signers.ts │ │ │ └── tests.ts │ │ │ ├── ethers │ │ │ ├── bignumber.ts │ │ │ ├── contracts.ts │ │ │ ├── events.ts │ │ │ └── provider.ts │ │ │ ├── hardhat │ │ │ ├── argument-types.ts │ │ │ ├── contracts.ts │ │ │ └── rpc.ts │ │ │ ├── io │ │ │ ├── logger.ts │ │ │ └── prompter.ts │ │ │ ├── merkle-tree │ │ │ ├── balance-tree.ts │ │ │ ├── merkle-tree.ts │ │ │ └── parse-balance-tree.ts │ │ │ ├── misc │ │ │ ├── array.ts │ │ │ ├── clone.ts │ │ │ ├── dates.ts │ │ │ ├── git.ts │ │ │ └── strings.ts │ │ │ ├── mocha │ │ │ ├── mocha-helpers.ts │ │ │ └── snapshot.ts │ │ │ └── solidity │ │ │ └── compiler.ts │ └── test │ │ ├── fixtures │ │ ├── asts.json │ │ ├── deployment-tx-receipt.ts │ │ ├── dummy-abi.json │ │ ├── event-abi.ts │ │ ├── initializable-ast.json │ │ ├── no-contract-ast.json │ │ ├── parsed-tx-receipt.ts │ │ ├── require-all-example │ │ │ ├── 1-one.ts │ │ │ ├── 2-two.json │ │ │ └── 3-three.yml │ │ ├── sample-project │ │ │ ├── contracts │ │ │ │ ├── AnotherModule.sol │ │ │ │ ├── ElectionStorage.sol │ │ │ │ ├── MultipleInheritance.sol │ │ │ │ ├── SampleModule.sol │ │ │ │ ├── Token.sol │ │ │ │ └── TokenModule.sol │ │ │ └── hardhat.config.ts │ │ ├── unparsed-tx-receipt.ts │ │ └── variableDefNodeAst.json │ │ ├── helpers │ │ └── parse-contracts.ts │ │ └── utils │ │ ├── assertions │ │ ├── assert-bignumber.test.ts │ │ └── assert-revert.test.ts │ │ ├── ast │ │ ├── comparator.test.ts │ │ ├── finders.test.ts │ │ └── storage-struct.test.ts │ │ ├── ethers │ │ ├── bignumber.test.ts │ │ ├── contracts.test.ts │ │ └── events.test.ts │ │ ├── hardhat │ │ ├── argument-types.test.ts │ │ └── rpc.test.ts │ │ ├── io │ │ ├── logger.test.ts │ │ └── prompter.test.ts │ │ ├── merkle-tree │ │ ├── balance-tree.test.ts │ │ ├── merkle-tree.test.ts │ │ └── parse-balance-tree.test.ts │ │ ├── misc │ │ ├── array.test.ts │ │ ├── dates.test.ts │ │ ├── git.test.ts │ │ └── strings.test.ts │ │ └── mocha │ │ └── mocha-helpers.test.ts ├── deps │ ├── .eslintrc │ ├── circular.js │ ├── deps.js │ ├── lib │ │ ├── colors.js │ │ ├── exec.js │ │ └── workspaces.js │ ├── mismatched.js │ └── package.json ├── docgen │ ├── .gitignore │ ├── docgen-contracts.sh │ ├── index.d.ts │ ├── index.js │ ├── natspec │ │ └── theme │ │ │ ├── common.hbs │ │ │ ├── contract.hbs │ │ │ ├── helpers.ts │ │ │ └── page.hbs │ └── package.json ├── eslint-plugin-progress │ ├── index.js │ └── package.json ├── hardhat-storage │ ├── README.md │ ├── jest.config.ts │ ├── package.json │ ├── src │ │ ├── index.ts │ │ ├── internal │ │ │ ├── are-deep-equal.ts │ │ │ ├── artifacts.ts │ │ │ ├── dump.ts │ │ │ ├── error.ts │ │ │ ├── file-helpers.ts │ │ │ ├── finders.ts │ │ │ ├── is-present.ts │ │ │ ├── iterators.ts │ │ │ ├── layout.ts │ │ │ ├── log-in-chunks.ts │ │ │ ├── path-helpers.ts │ │ │ ├── quiet-compile.ts │ │ │ ├── read-hardhat-artifact.ts │ │ │ ├── render-template.ts │ │ │ ├── render-testable-storage.ts │ │ │ ├── render.ts │ │ │ ├── validate-namespace.ts │ │ │ ├── validate-variables.ts │ │ │ └── verify-mutations.ts │ │ ├── subtasks │ │ │ ├── generate-testable-storage.ts │ │ │ ├── get-artifacts.ts │ │ │ ├── validate-contracts.ts │ │ │ └── verify-contracts.ts │ │ ├── task-names.ts │ │ ├── tasks │ │ │ ├── dump.ts │ │ │ ├── generate-testable.ts │ │ │ ├── layout.ts │ │ │ ├── validate.ts │ │ │ └── verify.ts │ │ ├── tsconfig.json │ │ ├── type-extensions.ts │ │ └── types.ts │ ├── templates │ │ └── TestableStorage.sol.mustache │ └── test │ │ ├── fixtures │ │ └── ExampleContract.sol │ │ ├── src │ │ └── internal │ │ │ ├── __snapshots__ │ │ │ └── dump.test.ts.snap │ │ │ ├── dump.test.ts │ │ │ ├── layout.test.ts │ │ │ └── verify-mutations.test.ts │ │ └── tsconfig.json └── sample-project │ ├── .gitignore │ ├── cannonfile.toml │ ├── contracts │ ├── Proxy.sol │ ├── interfaces │ │ ├── IAnotherModule.sol │ │ ├── IInitializableModule.sol │ │ ├── INewModule.sol │ │ ├── ISettingsModule.sol │ │ ├── ISomeModule.sol │ │ ├── ISomeModuleModified.sol │ │ └── ITokenModule.sol │ ├── modules │ │ ├── AnotherModule.sol │ │ ├── CoreModule.sol │ │ ├── InitializableModule.sol │ │ ├── SettingsModule.sol │ │ └── SomeModule.sol │ ├── storage │ │ ├── GlobalStorage.sol │ │ ├── InitializableStorage.sol │ │ └── SettingsStorage.sol │ └── test │ │ └── Destroyer.sol │ ├── hardhat.config.js │ ├── package.json │ ├── storage.dump.json │ └── test │ ├── bootstrap.js │ └── contracts │ ├── SettingsModule.test.js │ └── SomeModule.test.js └── yarn.lock /.env.sample: -------------------------------------------------------------------------------- 1 | DEPLOYER_PRIVATE_KEY= 2 | INFURA_API_KEY= 3 | INFURA_IPFS_ID= 4 | INFURA_IPFS_SECRET= 5 | ETHERSCAN_API_KEY= 6 | OVM_ETHERSCAN_API_KEY= 7 | CANNON_REGISTRY_PRIORITY= 8 | REPORT_GAS= 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .env 3 | .nyc_output 4 | .vscode 5 | **/coverage* 6 | **/deployments 7 | /**/test/generated 8 | /**/contracts/generated 9 | /utils/hardhat-router/test 10 | **/contracts/routers 11 | **/lib 12 | 13 | artifacts 14 | cache 15 | coverage 16 | dist 17 | node_modules 18 | Router.sol 19 | typechain-types 20 | lerna-debug.log 21 | docs/ 22 | junit 23 | storage.new.dump.json 24 | 25 | # Yarn v3 26 | .pnp.* 27 | .yarn/* 28 | !.yarn/patches 29 | !.yarn/plugins 30 | !.yarn/releases 31 | !.yarn/sdks 32 | !.yarn/versions 33 | 34 | tsconfig.tsbuildinfo 35 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | save-exact=true 2 | save-prefix='' 3 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | checksumBehavior: throw 2 | 3 | compressionLevel: mixed 4 | 5 | enableGlobalCache: true 6 | 7 | nodeLinker: node-modules 8 | 9 | npmRegistryServer: "https://registry.npmjs.org" 10 | 11 | supportedArchitectures: 12 | cpu: 13 | - x64 14 | - arm64 15 | libc: 16 | - glibc 17 | - musl 18 | os: 19 | - darwin 20 | - linux 21 | 22 | yarnPath: .yarn/releases/yarn-4.7.0.cjs 23 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | Synthetix contracts have been audited by Iosiro, OpenZeppelin, and Macro. Please see our Discord for detailed audit reports for each release. 4 | 5 | ## Reporting a Vulnerability 6 | 7 | We offer a bug bounty program through [Immunefi](https://immunefi.com/bounty/synthetix/). Please do not report vulnerabilities through any other channels, as we only accept security disclosures through Immunefy. 8 | -------------------------------------------------------------------------------- /auxiliary/ArbitrumGasPriceOracle/.gitignore: -------------------------------------------------------------------------------- 1 | cannon 2 | test/generated 3 | contracts/generated 4 | contracts/modules/test 5 | contracts/Router.sol 6 | deployments/hardhat 7 | deployments/local 8 | typechain-types 9 | -------------------------------------------------------------------------------- /auxiliary/ArbitrumGasPriceOracle/README.md: -------------------------------------------------------------------------------- 1 | ### Synthetix-auxiliary 2 | 3 | - This package houses any external contracts (i.e external oracle manager nodes) which the core/markets systems use. 4 | 5 | #### Arbitrum Gas Price Oracle 6 | 7 | TODO 8 | 9 | - Precompiles 10 | - L1 Batching Costs 11 | - Buffers 12 | - L2 Gas Price 13 | - etc. 14 | -------------------------------------------------------------------------------- /auxiliary/ArbitrumGasPriceOracle/cannonfile.test.toml: -------------------------------------------------------------------------------- 1 | name = "arbitrum-gas-price-oracle" 2 | version = "<%= package.version %>-testable" 3 | -------------------------------------------------------------------------------- /auxiliary/ArbitrumGasPriceOracle/cannonfile.toml: -------------------------------------------------------------------------------- 1 | name = "arbitrum-gas-price-oracle" 2 | version = "<%= package.version %>" 3 | description = "Arbiturm Gas Price Oracle Node" 4 | 5 | [setting.arbGasPriceOracleAddress] 6 | defaultValue = "0x000000000000000000000000000000000000006C" 7 | 8 | [contract.ArbGasPriceOracle] 9 | artifact = "contracts/ArbGasPriceOracle.sol:ArbGasPriceOracle" 10 | args = ["<%= settings.arbGasPriceOracleAddress %>"] 11 | create2 = true 12 | -------------------------------------------------------------------------------- /auxiliary/ArbitrumGasPriceOracle/foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | allow_paths = ["../../"] 3 | -------------------------------------------------------------------------------- /auxiliary/ArbitrumGasPriceOracle/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import commonConfig from '@synthetixio/common-config/hardhat.config'; 2 | 3 | import 'solidity-docgen'; 4 | import { templates } from '@synthetixio/docgen'; 5 | 6 | const config = { 7 | ...commonConfig, 8 | docgen: { 9 | exclude: [ 10 | './interfaces/external', 11 | './modules', 12 | './mixins', 13 | './mocks', 14 | './utils', 15 | './storage', 16 | './Proxy.sol', 17 | './Router.sol', 18 | ], 19 | templates, 20 | }, 21 | }; 22 | 23 | export default config; 24 | -------------------------------------------------------------------------------- /auxiliary/ArbitrumGasPriceOracle/remappings.txt: -------------------------------------------------------------------------------- 1 | @synthetixio/core-contracts=../../utils/core-contracts 2 | @synthetixio/oracle-manager=../../protocol/oracle-manager 3 | -------------------------------------------------------------------------------- /auxiliary/BuybackSnx/.gitignore: -------------------------------------------------------------------------------- 1 | cannon 2 | test/generated 3 | contracts/generated 4 | contracts/modules/test 5 | contracts/Router.sol 6 | deployments/hardhat 7 | deployments/local 8 | typechain-types 9 | -------------------------------------------------------------------------------- /auxiliary/BuybackSnx/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import commonConfig from '@synthetixio/common-config/hardhat.config'; 2 | 3 | import 'solidity-docgen'; 4 | import { templates } from '@synthetixio/docgen'; 5 | 6 | const config = { 7 | ...commonConfig, 8 | docgen: { 9 | exclude: [ 10 | './interfaces/external', 11 | './modules', 12 | './mixins', 13 | './mocks', 14 | './utils', 15 | './storage', 16 | './Proxy.sol', 17 | './Router.sol', 18 | ], 19 | templates, 20 | }, 21 | }; 22 | 23 | export default config; 24 | -------------------------------------------------------------------------------- /auxiliary/BuybackSnx/storage.dump.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /auxiliary/ERC4626ToAssetsRatioOracle/.gitignore: -------------------------------------------------------------------------------- 1 | cannon 2 | contracts/generated 3 | contracts/modules/test 4 | contracts/Router.sol 5 | deployments/hardhat 6 | deployments/local 7 | typechain-types 8 | test/generated 9 | -------------------------------------------------------------------------------- /auxiliary/ERC4626ToAssetsRatioOracle/contracts/interfaces/IERC20Metadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol) 3 | 4 | pragma solidity ^0.8.20; 5 | 6 | import {IERC20} from "./IERC20.sol"; 7 | 8 | /** 9 | * @dev Interface for the optional metadata functions from the ERC-20 standard. 10 | */ 11 | interface IERC20Metadata is IERC20 { 12 | /** 13 | * @dev Returns the name of the token. 14 | */ 15 | function name() external view returns (string memory); 16 | 17 | /** 18 | * @dev Returns the symbol of the token. 19 | */ 20 | function symbol() external view returns (string memory); 21 | 22 | /** 23 | * @dev Returns the decimals places of the token. 24 | */ 25 | function decimals() external view returns (uint8); 26 | } 27 | -------------------------------------------------------------------------------- /auxiliary/ERC4626ToAssetsRatioOracle/contracts/mocks/ERC20Mock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | contract ERC20Mock { 5 | function decimals() external pure returns (uint8) { 6 | return 6; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /auxiliary/ERC4626ToAssetsRatioOracle/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import commonConfig from '@synthetixio/common-config/hardhat.config'; 2 | 3 | import 'solidity-docgen'; 4 | import { templates } from '@synthetixio/docgen'; 5 | 6 | const config = { 7 | ...commonConfig, 8 | docgen: { 9 | exclude: [ 10 | './interfaces/external', 11 | './modules', 12 | './mixins', 13 | './mocks', 14 | './utils', 15 | './storage', 16 | './Proxy.sol', 17 | './Router.sol', 18 | ], 19 | templates, 20 | }, 21 | }; 22 | 23 | export default config; 24 | -------------------------------------------------------------------------------- /auxiliary/ERC4626ToAssetsRatioOracle/storage.dump.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /auxiliary/OpGasPriceOracle/.gitignore: -------------------------------------------------------------------------------- 1 | cannon 2 | contracts/generated 3 | contracts/modules/test 4 | contracts/Router.sol 5 | deployments/hardhat 6 | deployments/local 7 | typechain-types 8 | -------------------------------------------------------------------------------- /auxiliary/OpGasPriceOracle/cannonfile.test.toml: -------------------------------------------------------------------------------- 1 | version = "<%= package.version %>-testable" 2 | include = ["cannonfile.toml"] 3 | -------------------------------------------------------------------------------- /auxiliary/OpGasPriceOracle/cannonfile.toml: -------------------------------------------------------------------------------- 1 | name = "op-gas-price-oracle" 2 | version = "<%= package.version %>" 3 | description = "Optimism Gas Price Oracle Node" 4 | 5 | [setting.ovmGasPriceOracleAddress] 6 | defaultValue = "0x420000000000000000000000000000000000000F" 7 | 8 | [contract.OpGasPriceOracle] 9 | artifact = "contracts/OpGasPriceOracle.sol:OpGasPriceOracle" 10 | args = ["<%= settings.ovmGasPriceOracleAddress %>"] 11 | create2 = true 12 | -------------------------------------------------------------------------------- /auxiliary/OpGasPriceOracle/foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | allow_paths = ["../../"] 3 | -------------------------------------------------------------------------------- /auxiliary/OpGasPriceOracle/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import commonConfig from '@synthetixio/common-config/hardhat.config'; 2 | 3 | import 'solidity-docgen'; 4 | import { templates } from '@synthetixio/docgen'; 5 | 6 | const config = { 7 | ...commonConfig, 8 | docgen: { 9 | exclude: [ 10 | './interfaces/external', 11 | './modules', 12 | './mixins', 13 | './mocks', 14 | './utils', 15 | './storage', 16 | './Proxy.sol', 17 | './Router.sol', 18 | ], 19 | templates, 20 | }, 21 | }; 22 | 23 | export default config; 24 | -------------------------------------------------------------------------------- /auxiliary/OpGasPriceOracle/remappings.txt: -------------------------------------------------------------------------------- 1 | @synthetixio/core-contracts=../../utils/core-contracts 2 | @synthetixio/oracle-manager=../../protocol/oracle-manager 3 | -------------------------------------------------------------------------------- /auxiliary/OwnedFeeCollector/.gitignore: -------------------------------------------------------------------------------- 1 | cannon 2 | test/generated 3 | contracts/generated 4 | contracts/modules/test 5 | contracts/Router.sol 6 | deployments/hardhat 7 | deployments/local 8 | typechain-types 9 | -------------------------------------------------------------------------------- /auxiliary/OwnedFeeCollector/cannonfile.test.toml: -------------------------------------------------------------------------------- 1 | name = "owned-fee-collector" 2 | version = "<%= package.version %>-testable" 3 | 4 | [setting.owner] 5 | defaultValue = "0x48914229deDd5A9922f44441ffCCfC2Cb7856Ee9" 6 | 7 | [setting.fee_share_recipient] 8 | defaultValue = "0x48914229deDd5A9922f44441ffCCfC2Cb7856Ee9" 9 | 10 | [setting.fee_share] 11 | defaultValue = "500000000000000000" 12 | 13 | [provision.usd] 14 | source = "mintable-token:1.8@permissionless-mint" 15 | options.symbol = "USD" 16 | options.name = "Mintable USD" 17 | options.salt = "usd" 18 | 19 | [contract.owned_fee_collector] 20 | artifact = "contracts/OwnedFeeCollector.sol:OwnedFeeCollector" 21 | args = [ 22 | "<%= settings.owner %>", 23 | "<%= settings.fee_share_recipient %>", 24 | "<%= settings.fee_share %>", 25 | "<%= imports.usd.contracts.MintableToken.address %>", 26 | ] 27 | create2 = true 28 | -------------------------------------------------------------------------------- /auxiliary/OwnedFeeCollector/cannonfile.toml: -------------------------------------------------------------------------------- 1 | name = "owned-fee-collector" 2 | version = "<%= package.version %>" 3 | description = "Collects fees on behalf of an owner" 4 | 5 | [setting.owner] 6 | defaultValue = "0xD3DFa13CDc7c133b1700c243f03A8C6Df513A93b" 7 | 8 | [setting.fee_share_recipient] 9 | defaultValue = "0x14E4f1DE5cA748Fb130711f41473f1d2bc80523a" 10 | 11 | [setting.fee_share] 12 | defaultValue = "400000000000000000" 13 | 14 | [setting.fee_token] 15 | defaultValue = "0xb2F30A7C980f052f02563fb518dcc39e6bf38175" 16 | 17 | [contract.owned_fee_collector] 18 | artifact = "contracts/OwnedFeeCollector.sol:OwnedFeeCollector" 19 | args = [ 20 | "<%= settings.owner %>", 21 | "<%= settings.fee_share_recipient %>", 22 | "<%= settings.fee_share %>", 23 | "<%= settings.fee_token %>", 24 | ] 25 | create2 = true 26 | -------------------------------------------------------------------------------- /auxiliary/OwnedFeeCollector/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import commonConfig from '@synthetixio/common-config/hardhat.config'; 2 | 3 | import 'solidity-docgen'; 4 | import { templates } from '@synthetixio/docgen'; 5 | 6 | const config = { 7 | ...commonConfig, 8 | docgen: { 9 | exclude: [ 10 | './interfaces/external', 11 | './modules', 12 | './mixins', 13 | './mocks', 14 | './utils', 15 | './storage', 16 | './Proxy.sol', 17 | './Router.sol', 18 | ], 19 | templates, 20 | }, 21 | }; 22 | 23 | export default config; 24 | -------------------------------------------------------------------------------- /auxiliary/PythERC7412Wrapper/.gitignore: -------------------------------------------------------------------------------- 1 | cannon 2 | contracts/generated 3 | contracts/modules/test 4 | contracts/Router.sol 5 | deployments/hardhat 6 | deployments/local 7 | typechain-types 8 | -------------------------------------------------------------------------------- /auxiliary/PythERC7412Wrapper/cannonfile.test.toml: -------------------------------------------------------------------------------- 1 | version = "<%= package.version %>-testable" 2 | include = ["cannonfile.toml"] 3 | -------------------------------------------------------------------------------- /auxiliary/PythERC7412Wrapper/cannonfile.toml: -------------------------------------------------------------------------------- 1 | name = "pyth-erc7412-wrapper" 2 | version = "<%= package.version %>" 3 | description = "Benchmark prices oracle" 4 | 5 | [setting.pythAddress] 6 | defaultValue = "0x420000000000000000000000000000000000000F" 7 | 8 | [contract.PythERC7412Wrapper] 9 | artifact = "contracts/PythERC7412Wrapper.sol:PythERC7412Wrapper" 10 | args = ["<%= settings.pythAddress %>"] 11 | create2 = true 12 | -------------------------------------------------------------------------------- /auxiliary/PythERC7412Wrapper/contracts/interfaces/IERC7412.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.11 <0.9.0; 2 | 3 | interface IERC7412 { 4 | error FeeRequired(uint256 amount); 5 | error OracleDataRequired(address oracleContract, bytes oracleQuery); 6 | 7 | function oracleId() external view returns (bytes32 oracleId); 8 | 9 | function fulfillOracleQuery(bytes calldata signedOffchainData) external payable; 10 | } 11 | -------------------------------------------------------------------------------- /auxiliary/PythERC7412Wrapper/contracts/storage/Price.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {PythStructs, IPyth} from "@synthetixio/oracle-manager/contracts/interfaces/external/IPyth.sol"; 5 | 6 | /** 7 | * @title Benchmark price storage for a specific price id. 8 | */ 9 | library Price { 10 | struct Data { 11 | /** 12 | * @dev The price mapping for timestamps 13 | */ 14 | mapping(uint64 => PythStructs.Price) benchmarkPrices; 15 | } 16 | 17 | function load(bytes32 priceId) internal pure returns (Data storage price) { 18 | bytes32 s = keccak256(abi.encode("io.synthetix.pyth-erc7412-wrapper.price", priceId)); 19 | assembly { 20 | price.slot := s 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /auxiliary/PythERC7412Wrapper/foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | allow_paths = ["../../"] 3 | -------------------------------------------------------------------------------- /auxiliary/PythERC7412Wrapper/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import commonConfig from '@synthetixio/common-config/hardhat.config'; 2 | 3 | import 'solidity-docgen'; 4 | import { templates } from '@synthetixio/docgen'; 5 | 6 | const config = { 7 | ...commonConfig, 8 | docgen: { 9 | exclude: [ 10 | './interfaces/external', 11 | './modules', 12 | './mixins', 13 | './mocks', 14 | './utils', 15 | './storage', 16 | './Proxy.sol', 17 | './Router.sol', 18 | ], 19 | templates, 20 | }, 21 | }; 22 | 23 | export default config; 24 | -------------------------------------------------------------------------------- /auxiliary/PythERC7412Wrapper/remappings.txt: -------------------------------------------------------------------------------- 1 | @synthetixio/core-contracts=../../utils/core-contracts 2 | @synthetixio/oracle-manager=../../protocol/oracle-manager 3 | -------------------------------------------------------------------------------- /auxiliary/README.md: -------------------------------------------------------------------------------- 1 | ### Synthetix-auxiliary 2 | 3 | - This package houses any external contracts (i.e external oracle manager nodes) which the core/markets systems use. 4 | -------------------------------------------------------------------------------- /auxiliary/RewardsDistributor/.gitignore: -------------------------------------------------------------------------------- 1 | cache/ 2 | out/ 3 | lcov.info 4 | -------------------------------------------------------------------------------- /auxiliary/RewardsDistributor/README.md: -------------------------------------------------------------------------------- 1 | Official Rewards Distributor for intreacting with [Synthetix V3](https://docs.synthetix.io/v/v3/for-liquidity-pool-managers/rewards-distributors) 2 | 3 | ## Running tests 4 | 5 | ```sh 6 | forge test -vvvvv --watch src test 7 | ``` 8 | 9 | Coverage report 10 | 11 | ```sh 12 | forge coverage --report lcov 13 | genhtml ./lcov.info --output-directory coverage 14 | ``` 15 | 16 | To install `genhtml`: 17 | 18 | ```sh 19 | brew install lcov 20 | ``` 21 | -------------------------------------------------------------------------------- /auxiliary/RewardsDistributor/cannonfile.snapshot.toml: -------------------------------------------------------------------------------- 1 | name = "synthetix-snapshot-rewards" 2 | version = "<%= package.version %>" 3 | description = "Maintains snapshots of account balances in a pool" 4 | 5 | [setting.synthetixPackage] 6 | defaultValue = "synthetix:latest@main" 7 | 8 | [setting.servicePoolId] 9 | defaultValue = "0" 10 | 11 | [setting.serviceCollateralAddress] 12 | defaultValue = "<%= AddressZero %>" 13 | 14 | [setting.snapper] 15 | defaultValue = "<%= AddressZero %>" 16 | 17 | [import.synthetix] 18 | source = "<%= settings.synthetixPackage %>" 19 | 20 | [contract.RewardsDistributor] 21 | artifact = "SnapshotRewardsDistributor" 22 | args = [ 23 | "<%= imports.synthetix.contracts.CoreProxy.address %>", 24 | "<%= settings.servicePoolId %>", 25 | "<%= settings.serviceCollateralAddress %>", 26 | "<%= settings.snapper %>", 27 | ] 28 | -------------------------------------------------------------------------------- /auxiliary/RewardsDistributor/foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = "src" 3 | out = "out" 4 | libs = [] 5 | allow_paths = [ 6 | "../../node_modules/forge-std", 7 | "../../protocol/synthetix", 8 | "../../utils/core-contracts", 9 | ] 10 | remappings = [ 11 | "forge-std=../../node_modules/forge-std/src", 12 | "@synthetixio=../../node_modules/@synthetixio", 13 | ] 14 | 15 | fs_permissions = [{ access = "read", path = "./" }] 16 | -------------------------------------------------------------------------------- /auxiliary/RewardsDistributor/test/MintableToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.21; 3 | 4 | import {MockERC20} from "forge-std/mocks/MockERC20.sol"; 5 | 6 | contract MintableToken is MockERC20 { 7 | constructor(string memory _symbol, uint8 _decimals) { 8 | initialize(string.concat("Mintable token ", _symbol), _symbol, _decimals); 9 | } 10 | 11 | function mint(address to, uint256 amount) public { 12 | _mint(to, amount); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /auxiliary/RewardsDistributorExternal/.gitignore: -------------------------------------------------------------------------------- 1 | cache/ 2 | out/ 3 | lcov.info 4 | -------------------------------------------------------------------------------- /auxiliary/RewardsDistributorExternal/README.md: -------------------------------------------------------------------------------- 1 | Official Rewards Distributor for intreacting with [Synthetix V3](https://docs.synthetix.io/v/v3/for-liquidity-pool-managers/rewards-distributors) 2 | 3 | ## Running tests 4 | 5 | ```sh 6 | forge test -vvvvv --watch src test 7 | ``` 8 | 9 | Coverage report 10 | 11 | ```sh 12 | forge coverage --report lcov 13 | genhtml ./lcov.info --output-directory coverage 14 | ``` 15 | 16 | To install `genhtml`: 17 | 18 | ```sh 19 | brew install lcov 20 | ``` 21 | -------------------------------------------------------------------------------- /auxiliary/RewardsDistributorExternal/foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = "src" 3 | out = "out" 4 | libs = [] 5 | allow_paths = [ 6 | "../../node_modules/forge-std", 7 | "../../protocol/synthetix", 8 | "../../utils/core-contracts", 9 | ] 10 | remappings = [ 11 | "forge-std=../../node_modules/forge-std/src", 12 | "@synthetixio=../../node_modules/@synthetixio", 13 | ] 14 | 15 | fs_permissions = [{ access = "read", path = "./" }] 16 | -------------------------------------------------------------------------------- /auxiliary/RewardsDistributorExternal/test/MintableToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.21; 3 | 4 | import {MockERC20} from "forge-std/mocks/MockERC20.sol"; 5 | 6 | contract MintableToken is MockERC20 { 7 | constructor(string memory _symbol, uint8 _decimals) { 8 | initialize(string.concat("Mintable token ", _symbol), _symbol, _decimals); 9 | } 10 | 11 | function mint(address to, uint256 amount) public { 12 | _mint(to, amount); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /auxiliary/SpotMarketOracle/.gitignore: -------------------------------------------------------------------------------- 1 | cannon 2 | contracts/generated 3 | contracts/modules/test 4 | contracts/Router.sol 5 | deployments/hardhat 6 | deployments/local 7 | typechain-types 8 | -------------------------------------------------------------------------------- /auxiliary/SpotMarketOracle/cannonfile.test.toml: -------------------------------------------------------------------------------- 1 | version = "<%= package.version %>-testable" 2 | include = ["cannonfile.toml"] 3 | -------------------------------------------------------------------------------- /auxiliary/SpotMarketOracle/cannonfile.toml: -------------------------------------------------------------------------------- 1 | name = "spot-market-oracle" 2 | version = "<%= package.version %>" 3 | description = "Spot market quoting oracle" 4 | 5 | [setting.spotMarketAddress] 6 | defaultValue = "0x41A883a85b1AdE59F41d459Fa550b40fa56429DB" # for base goerli andromeda 7 | 8 | [contract.SpotMarketOracle] 9 | artifact = "contracts/SpotMarketOracle.sol:SpotMarketOracle" 10 | args = ["<%= settings.spotMarketAddress %>"] 11 | create2 = true 12 | -------------------------------------------------------------------------------- /auxiliary/SpotMarketOracle/contracts/interfaces/ISpotMarketSystem.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {IAtomicOrderModule} from "@synthetixio/spot-market/contracts/interfaces/IAtomicOrderModule.sol"; 5 | import {ISpotMarketFactoryModule} from "@synthetixio/spot-market/contracts/interfaces/ISpotMarketFactoryModule.sol"; 6 | 7 | // solhint-disable-next-line no-empty-blocks 8 | interface ISpotMarketSystem is IAtomicOrderModule, ISpotMarketFactoryModule {} 9 | -------------------------------------------------------------------------------- /auxiliary/SpotMarketOracle/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import commonConfig from '@synthetixio/common-config/hardhat.config'; 2 | 3 | import 'solidity-docgen'; 4 | import { templates } from '@synthetixio/docgen'; 5 | 6 | const config = { 7 | ...commonConfig, 8 | docgen: { 9 | exclude: [ 10 | './interfaces/external', 11 | './modules', 12 | './mixins', 13 | './mocks', 14 | './utils', 15 | './storage', 16 | './Proxy.sol', 17 | './Router.sol', 18 | ], 19 | templates, 20 | }, 21 | }; 22 | 23 | export default config; 24 | -------------------------------------------------------------------------------- /auxiliary/SpotMarketOracle/storage.dump.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /auxiliary/TrustedMulticallForwarder/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiler files 2 | cache/ 3 | out/ 4 | 5 | # Libs 6 | lib/ 7 | 8 | # Ignores development broadcast logs 9 | !/broadcast 10 | /broadcast/*/31337/ 11 | /broadcast/**/dry-run/ 12 | 13 | # Docs 14 | docs/ 15 | 16 | # Dotenv file 17 | .env 18 | 19 | # Solidity Artifacts 20 | out/ 21 | -------------------------------------------------------------------------------- /auxiliary/TrustedMulticallForwarder/README.md: -------------------------------------------------------------------------------- 1 | ## Trusted Multicall Forwarder 2 | 3 | ERC-2771 compliant trusted forwarder including Multicall3 functionality with error bubbling 4 | 5 | ## Build Project 6 | 7 | Make sure to install the required dependencies: 8 | 9 | ```bash 10 | forge install OpenZeppelin/openzeppelin-contracts@v5.0.0 --no-git 11 | forge install foundry-rs/forge-std --no-git 12 | ``` 13 | -------------------------------------------------------------------------------- /auxiliary/TrustedMulticallForwarder/cannonfile.clone.toml: -------------------------------------------------------------------------------- 1 | name = "trusted-multicall-forwarder" 2 | version = "0.0.3" 3 | description = "ERC-2771 compliant trusted forwarder including Multicall3 functionality with error bubbling" 4 | preset = "from-clone" 5 | 6 | [setting.salt] 7 | defaultValue = "salt" 8 | 9 | [clone.trusted_multicall_forwarder] 10 | source = "trusted-multicall-forwarder" 11 | target = "trusted-multicall-forwarder@with-synthetix" 12 | options.salt = "<%= settings.salt %>" 13 | -------------------------------------------------------------------------------- /auxiliary/TrustedMulticallForwarder/cannonfile.toml: -------------------------------------------------------------------------------- 1 | name = "trusted-multicall-forwarder" 2 | version = "0.0.4" 3 | description = "ERC-2771 compliant trusted forwarder including Multicall3 functionality with error bubbling" 4 | 5 | [setting.salt] 6 | defaultValue = "salt" 7 | 8 | [contract.TrustedMulticallForwarder] 9 | artifact = "TrustedMulticallForwarder" 10 | salt = "<%= settings.salt %>" 11 | create2 = true 12 | ifExists = "continue" 13 | -------------------------------------------------------------------------------- /auxiliary/TrustedMulticallForwarder/foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = 'src' 3 | test = 'test/' 4 | out = 'out' 5 | libs = ['lib'] 6 | solc_version = "0.8.20" 7 | optimizer = true 8 | optimizer_runs = 1_000_000 9 | 10 | [fmt] 11 | line_length = 80 12 | number_underscore = "thousands" 13 | -------------------------------------------------------------------------------- /auxiliary/TrustedMulticallForwarder/remappings.txt: -------------------------------------------------------------------------------- 1 | @openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/ 2 | ds-test/=lib/forge-std/lib/ds-test/src/ 3 | erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/ 4 | forge-std/=lib/forge-std/src/ 5 | openzeppelin-contracts/=lib/openzeppelin-contracts/ 6 | -------------------------------------------------------------------------------- /auxiliary/TrustedMulticallForwarder/test/mocks/EtherSink.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.20; 3 | 4 | /// @title EtherSink 5 | /// @notice Receives Ether, that's about it \( o_o )/ 6 | /// @author andreas@nascent.xyz 7 | contract EtherSink { 8 | /// >>>>>>>>>>>>>>>>>>>>>> ACCEPT CALLS <<<<<<<<<<<<<<<<<<<<<<< /// 9 | 10 | /// @notice Allows the test to receive eth via low level calls 11 | receive() external payable {} 12 | } 13 | -------------------------------------------------------------------------------- /auxiliary/WstEthToStEthRatioOracle/.gitignore: -------------------------------------------------------------------------------- 1 | cannon 2 | contracts/generated 3 | contracts/modules/test 4 | contracts/Router.sol 5 | deployments/hardhat 6 | deployments/local 7 | typechain-types 8 | test/generated 9 | -------------------------------------------------------------------------------- /auxiliary/WstEthToStEthRatioOracle/cannonfile.toml: -------------------------------------------------------------------------------- 1 | name = "wsteth-to-steth-ratio-oracle" 2 | version = "<%= package.version %>" 3 | description = "<%= package.description %>" 4 | 5 | # @see: https://etherscan.io/token/0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0 6 | [setting.wsteth] 7 | defaultValue = "0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0" 8 | 9 | [contract.WstEthToStEthRatioOracle] 10 | artifact = "contracts/WstEthToStEthRatioOracle.sol:WstEthToStEthRatioOracle" 11 | args = ["<%= settings.wsteth %>"] 12 | -------------------------------------------------------------------------------- /auxiliary/WstEthToStEthRatioOracle/contracts/interfaces/IWstETH.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | interface IWstETH { 5 | /** 6 | * @notice Get amount of stETH for a given amount of wstETH 7 | * @param _wstETHAmount amount of wstETH 8 | * @return Amount of stETH for a given wstETH amount 9 | */ 10 | function getStETHByWstETH(uint256 _wstETHAmount) external view returns (uint256); 11 | } 12 | -------------------------------------------------------------------------------- /auxiliary/WstEthToStEthRatioOracle/contracts/mocks/AggregatorV3Mock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {AggregatorV3Mock as BaseAggregatorV3Mock} from "@synthetixio/main/contracts/mocks/AggregatorV3Mock.sol"; 5 | 6 | contract AggregatorV3Mock is BaseAggregatorV3Mock {} 7 | -------------------------------------------------------------------------------- /auxiliary/WstEthToStEthRatioOracle/contracts/mocks/WstETHMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {IWstETH} from "../interfaces/IWstETH.sol"; 5 | 6 | contract WstETHMock is IWstETH { 7 | uint256 wstEthToStEthRatio; 8 | 9 | function getStETHByWstETH(uint256) external view returns (uint256) { 10 | return wstEthToStEthRatio; 11 | } 12 | 13 | function mockSetWstEthToStEthRatio(uint256 _wstEthToStEthRatio) external { 14 | wstEthToStEthRatio = _wstEthToStEthRatio; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /auxiliary/WstEthToStEthRatioOracle/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import commonConfig from '@synthetixio/common-config/hardhat.config'; 2 | 3 | import 'solidity-docgen'; 4 | import { templates } from '@synthetixio/docgen'; 5 | 6 | const config = { 7 | ...commonConfig, 8 | docgen: { 9 | exclude: [ 10 | './interfaces/external', 11 | './modules', 12 | './mixins', 13 | './mocks', 14 | './utils', 15 | './storage', 16 | './Proxy.sol', 17 | './Router.sol', 18 | ], 19 | templates, 20 | }, 21 | }; 22 | 23 | export default config; 24 | -------------------------------------------------------------------------------- /auxiliary/WstEthToStEthRatioOracle/storage.dump.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /funding.json: -------------------------------------------------------------------------------- 1 | { 2 | "opRetro": { 3 | "projectId": "0xcf10a15439ef8c56e1b6c22641544012bfd032c7b584d1160a7d743cb770875b" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "node_modules/@lerna-lite/cli/schemas/lerna-schema.json", 3 | "useWorkspaces": true, 4 | "version": "3.12.3", 5 | "exact": true, 6 | "changelog": false, 7 | "ignoreChanges": [ 8 | "**/test/**", 9 | "**/*.md" 10 | ], 11 | "private": false, 12 | "push": true, 13 | "command": { 14 | "version": { 15 | "allowBranch": [ 16 | "main" 17 | ] 18 | }, 19 | "command": { 20 | "publish": { 21 | "removePackageFields": [ 22 | "devDependencies", 23 | "scripts", 24 | "depcheck" 25 | ] 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /markets/bfp-market/assets/diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Synthetixio/synthetix-v3/d795f6dcdcbc644f8dfbc684903c56f9b6e751e2/markets/bfp-market/assets/diagram.png -------------------------------------------------------------------------------- /markets/bfp-market/assets/overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Synthetixio/synthetix-v3/d795f6dcdcbc644f8dfbc684903c56f9b6e751e2/markets/bfp-market/assets/overview.png -------------------------------------------------------------------------------- /markets/bfp-market/contracts/Proxy.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {UUPSProxyWithOwner} from "@synthetixio/core-contracts/contracts/proxy/UUPSProxyWithOwner.sol"; 5 | 6 | contract Proxy is UUPSProxyWithOwner { 7 | // solhint-disable-next-line no-empty-blocks 8 | constructor( 9 | address firstImplementation, 10 | address initialOwner 11 | ) UUPSProxyWithOwner(firstImplementation, initialOwner) {} 12 | } 13 | -------------------------------------------------------------------------------- /markets/bfp-market/contracts/interfaces/IFeatureFlagModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {IFeatureFlagModule as IBaseFeatureFlagModule} from "@synthetixio/core-modules/contracts/interfaces/IFeatureFlagModule.sol"; 5 | 6 | interface IFeatureFlagModule is IBaseFeatureFlagModule { 7 | /// @notice Emitted when all features get suspended or enabled. 8 | /// @param suspended True to indicate the market was suspended or false if enabled 9 | event PerpMarketSuspended(bool suspended); 10 | 11 | /// @notice Suspends all features. Can be called by owner or a configured "denier". 12 | function suspendAllFeatures() external; 13 | 14 | /// @notice Enable all features. Can be called by owner. 15 | function enableAllFeatures() external; 16 | } 17 | -------------------------------------------------------------------------------- /markets/bfp-market/contracts/interfaces/hooks/ISettlementHook.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {IERC165} from "@synthetixio/core-contracts/contracts/interfaces/IERC165.sol"; 5 | 6 | interface ISettlementHook is IERC165 { 7 | /// @notice Invoked as the callback post order settlement. 8 | /// @param accountId Account of order that was just settled 9 | /// @param marketId Market the order was just settled on 10 | /// @param oraclePrice Pyth price used for settlement (note: not the entry fill price) 11 | /// @dev Implementers should verify the calling `msg.sender` is Synthetix BFP Market Proxy and 12 | /// be highly recommended that it should also be idempotent. 13 | function onSettle(uint128 accountId, uint128 marketId, uint256 oraclePrice) external; 14 | } 15 | -------------------------------------------------------------------------------- /markets/bfp-market/contracts/mocks/CollateralMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {CollateralMock as BaseCollateralMock} from "@synthetixio/main/contracts/mocks/CollateralMock.sol"; 5 | 6 | // solhint-disable-next-line no-empty-blocks 7 | contract CollateralMock is BaseCollateralMock {} 8 | -------------------------------------------------------------------------------- /markets/bfp-market/contracts/mocks/ExternalMocks.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/main/contracts/mocks/AggregatorV3Mock.sol"; 5 | -------------------------------------------------------------------------------- /markets/bfp-market/contracts/modules/CoreModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {CoreModule as BaseCoreModule} from "@synthetixio/core-modules/contracts/modules/CoreModule.sol"; 5 | 6 | // solhint-disable-next-line no-empty-blocks 7 | contract CoreModule is BaseCoreModule { 8 | // NOTE: Needed for UUPSProxy. 9 | } 10 | -------------------------------------------------------------------------------- /markets/bfp-market/contracts/storage/AddressRegistry.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {ITokenModule} from "@synthetixio/core-modules/contracts/interfaces/ITokenModule.sol"; 5 | import {ISynthetixSystem} from "../external/ISynthetixSystem.sol"; 6 | 7 | library AddressRegistry { 8 | struct Data { 9 | ISynthetixSystem synthetix; 10 | address sUsd; 11 | address oracleManager; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /markets/bfp-market/contracts/storage/SplitAccountConfiguration.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | library SplitAccountConfiguration { 5 | // --- Constants --- // 6 | 7 | bytes32 private constant GLOBAL_DATA_SLOT_NAME = 8 | keccak256(abi.encode("io.synthetix.bfp-market.SplitAccountConfiguration")); 9 | 10 | // --- Storage --- // 11 | 12 | struct GlobalData { 13 | /// {address => isEnabled}. 14 | mapping(address => bool) whitelisted; 15 | /// Array of whitelisted addresses (use whitelisted mapping). 16 | address[] whitelistedAddresses; 17 | } 18 | 19 | function load() internal pure returns (SplitAccountConfiguration.GlobalData storage d) { 20 | bytes32 s = GLOBAL_DATA_SLOT_NAME; 21 | assembly { 22 | d.slot := s 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /markets/bfp-market/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import commonConfig from '@synthetixio/common-config/hardhat.config'; 2 | 3 | import 'solidity-docgen'; 4 | import { templates } from '@synthetixio/docgen'; 5 | 6 | const config = { 7 | ...commonConfig, 8 | allowUnlimitedContractSize: true, 9 | docgen: { 10 | exclude: [ 11 | './external', 12 | './generated', 13 | './mocks', 14 | './modules', 15 | './storage', 16 | './utils', 17 | './Proxy.sol', 18 | ], 19 | templates, 20 | }, 21 | mocha: { 22 | timeout: 30_000, 23 | }, 24 | storage: { 25 | artifacts: [ 26 | ...commonConfig.storage.artifacts, 27 | '!contracts/modules/PerpRewardDistributorModule/PerpRewardDistributor.sol:PerpRewardDistributor', 28 | ], 29 | }, 30 | }; 31 | 32 | export default config; 33 | -------------------------------------------------------------------------------- /markets/bfp-market/scripts/stable_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function recursive_execution() { 4 | local dir="$1" 5 | 6 | for file in "$dir"/*; do 7 | if [ -f "$file" ]; then 8 | TS_NODE_SKIP_IGNORE=true hardhat test "$file" 9 | fi 10 | 11 | if [ -d "$file" ]; then 12 | recursive_execution "$file" 13 | fi 14 | done 15 | } 16 | 17 | recursive_execution ./test/integration 18 | -------------------------------------------------------------------------------- /markets/bfp-market/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "module": "CommonJS", 5 | "strict": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "resolveJsonModule": true, 9 | "skipLibCheck": true, 10 | "declaration": true, 11 | "declarationMap": true, 12 | "sourceMap": false, 13 | "noEmit": true 14 | }, 15 | "include": ["./scripts", "./test", "./typechain-types", "./typed"], 16 | "files": ["./hardhat.config.ts"] 17 | } 18 | -------------------------------------------------------------------------------- /markets/legacy-market/contracts/InitialModuleBundle.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/core-modules/contracts/modules/OwnerModule.sol"; 5 | import "@synthetixio/core-modules/contracts/modules/UpgradeModule.sol"; 6 | 7 | // The below contract is only used during initialization as a kernel for the first release which the system can be upgraded onto. 8 | // Subsequent upgrades will not need this module bundle 9 | // In the future on live networks, we may want to find some way to hardcode the owner address here to prevent grieving 10 | 11 | // solhint-disable-next-line no-empty-blocks 12 | contract InitialModuleBundle is OwnerModule, UpgradeModule { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /markets/legacy-market/contracts/Proxy.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {UUPSProxyWithOwner} from "@synthetixio/core-contracts/contracts/proxy/UUPSProxyWithOwner.sol"; 5 | 6 | contract Proxy is UUPSProxyWithOwner { 7 | // solhint-disable-next-line no-empty-blocks 8 | constructor( 9 | address firstImplementation, 10 | address initialOwner 11 | ) UUPSProxyWithOwner(firstImplementation, initialOwner) {} 12 | } 13 | -------------------------------------------------------------------------------- /markets/legacy-market/contracts/interfaces/ISNXDistributor.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title Rewards distributor for sending snx inflation or liquidation proceeds to the preferred pool 6 | */ 7 | interface ISNXDistributor { 8 | function notifyRewardAmount(uint256 reward) external; 9 | } 10 | -------------------------------------------------------------------------------- /markets/legacy-market/contracts/interfaces/external/IAddressResolver.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | // https://docs.synthetix.io/contracts/source/interfaces/iaddressresolver 5 | interface IAddressResolver { 6 | function getAddress(bytes32 name) external view returns (address); 7 | 8 | function getSynth(bytes32 key) external view returns (address); 9 | 10 | function requireAndGetAddress( 11 | bytes32 name, 12 | string calldata reason 13 | ) external view returns (address); 14 | } 15 | -------------------------------------------------------------------------------- /markets/legacy-market/contracts/interfaces/external/ILiquidatorRewards.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.11 <0.9.0; 2 | 3 | interface ILiquidatorRewards { 4 | // Views 5 | 6 | function earned(address account) external view returns (uint256); 7 | 8 | // Mutative 9 | 10 | function getReward(address account) external; 11 | 12 | function notifyRewardAmount(uint256 reward) external; 13 | 14 | function updateEntry(address account) external; 15 | } 16 | -------------------------------------------------------------------------------- /markets/legacy-market/contracts/interfaces/external/IRewardEscrowV2.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | library VestingEntries { 5 | struct VestingEntry { 6 | uint64 endTime; 7 | uint256 escrowAmount; 8 | } 9 | struct VestingEntryWithID { 10 | uint64 endTime; 11 | uint256 escrowAmount; 12 | uint256 entryID; 13 | } 14 | } 15 | 16 | interface IRewardEscrowV2 { 17 | function getVestingSchedules( 18 | address account, 19 | uint256 index, 20 | uint256 pageSize 21 | ) external view returns (VestingEntries.VestingEntryWithID[] memory); 22 | } 23 | -------------------------------------------------------------------------------- /markets/legacy-market/contracts/interfaces/external/ISynth.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.11 <0.9.0; 2 | 3 | // https://docs.synthetix.io/contracts/source/interfaces/isynth 4 | interface ISynth { 5 | // Views 6 | function currencyKey() external view returns (bytes32); 7 | 8 | function transferableSynths(address account) external view returns (uint256); 9 | 10 | // Mutative functions 11 | function transferAndSettle(address to, uint256 value) external returns (bool); 12 | 13 | function transferFromAndSettle(address from, address to, uint256 value) external returns (bool); 14 | 15 | // Restricted: used internally to Synthetix 16 | function burn(address account, uint256 amount) external; 17 | 18 | function issue(address account, uint256 amount) external; 19 | } 20 | -------------------------------------------------------------------------------- /markets/legacy-market/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import commonConfig from '@synthetixio/common-config/hardhat.config'; 2 | 3 | import 'solidity-docgen'; 4 | import { templates } from '@synthetixio/docgen'; 5 | 6 | const config = { 7 | ...commonConfig, 8 | docgen: { 9 | exclude: [ 10 | './generated', 11 | './interfaces/external', 12 | './InitialModuleBundle.sol', 13 | './LegacyMarket.sol', 14 | './Proxy.sol', 15 | './SNXDistributor.sol', 16 | ], 17 | templates, 18 | }, 19 | }; 20 | 21 | export default config; 22 | -------------------------------------------------------------------------------- /markets/legacy-market/regenerate-external-interfaces.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x 4 | 5 | CANNON="${CANNON:-cannon}" 6 | 7 | cannon inspect synthetix:latest --chain-id 1 --json | jq '.state["router.CoreRouter"].artifacts.contracts.CoreRouter.abi' -cM | abi-to-sol IV3CoreProxy -V '^0.8.4' > contracts/interfaces/external/IV3CoreProxy.sol 8 | -------------------------------------------------------------------------------- /markets/legacy-market/test/utils.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'ethers'; 2 | 3 | export function snapshotCheckpoint(provider: () => ethers.providers.JsonRpcProvider) { 4 | let snapshotId: number; 5 | 6 | before('snapshot', async () => { 7 | snapshotId = await provider().send('evm_snapshot', []); 8 | }); 9 | 10 | const restore = async () => { 11 | await provider().send('evm_revert', [snapshotId]); 12 | snapshotId = await provider().send('evm_snapshot', []); 13 | }; 14 | 15 | return restore; 16 | } 17 | -------------------------------------------------------------------------------- /markets/perps-market/.gitignore: -------------------------------------------------------------------------------- 1 | # generated test modules 2 | contracts/modules/test 3 | contracts/generated 4 | 5 | # generated routers 6 | contracts/routers 7 | -------------------------------------------------------------------------------- /markets/perps-market/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require('@synthetixio/common-config/.solcover.js'), 3 | skipFiles: ['mocks', 'Mocks.sol'], 4 | }; 5 | -------------------------------------------------------------------------------- /markets/perps-market/contracts/.gitignore: -------------------------------------------------------------------------------- 1 | Router.sol -------------------------------------------------------------------------------- /markets/perps-market/contracts/Mocks.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/main/contracts/mocks/AggregatorV3Mock.sol"; 5 | import "@synthetixio/oracle-manager/contracts/mocks/MockPythExternalNode.sol"; 6 | -------------------------------------------------------------------------------- /markets/perps-market/contracts/Proxy.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {UUPSProxyWithOwner} from "@synthetixio/core-contracts/contracts/proxy/UUPSProxyWithOwner.sol"; 5 | 6 | /** 7 | * Synthetix V3 Perps Factory -- Proxy Contract 8 | * 9 | * Visit https://usecannon.com/packages/synthetix-perps-market to interact with this protocol 10 | */ 11 | contract Proxy is UUPSProxyWithOwner { 12 | // solhint-disable-next-line no-empty-blocks 13 | constructor( 14 | address firstImplementation, 15 | address initialOwner 16 | ) UUPSProxyWithOwner(firstImplementation, initialOwner) {} 17 | } 18 | -------------------------------------------------------------------------------- /markets/perps-market/contracts/interfaces/IAccountEvents.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title Account events used on several places in the system. 6 | */ 7 | interface IAccountEvents { 8 | /** 9 | * @notice Gets fired anytime an account is charged with fees, paying settlement rewards. 10 | * @param accountId Id of the account being deducted. 11 | * @param amount Amount of synth market deducted from the account. 12 | * @param accountDebt current debt of the account after charged amount. 13 | */ 14 | event AccountCharged(uint128 accountId, int256 amount, uint256 accountDebt); 15 | } 16 | -------------------------------------------------------------------------------- /markets/perps-market/contracts/interfaces/IDistributorErrors.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title Distributor errors used on several places in the system. 6 | */ 7 | interface IDistributorErrors { 8 | /** 9 | * @notice Thrown when attempting to use a wrong distributor 10 | */ 11 | error InvalidDistributor(uint128 id, address distributor); 12 | 13 | /** 14 | * @notice Thrown when attempting to use a wrong contract as distributor 15 | */ 16 | error InvalidDistributorContract(address distributor); 17 | } 18 | -------------------------------------------------------------------------------- /markets/perps-market/contracts/interfaces/external/IPythERC7412Wrapper.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | interface IPythERC7412Wrapper { 5 | error OracleDataRequired(address oracleContract, bytes oracleQuery); 6 | 7 | function getBenchmarkPrice( 8 | bytes32 priceId, 9 | uint64 requestedTime 10 | ) external view returns (int256); 11 | } 12 | -------------------------------------------------------------------------------- /markets/perps-market/contracts/interfaces/external/ISpotMarketSystem.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {IAtomicOrderModule} from "@synthetixio/spot-market/contracts/interfaces/IAtomicOrderModule.sol"; 5 | import {ISpotMarketFactoryModule} from "@synthetixio/spot-market/contracts/interfaces/ISpotMarketFactoryModule.sol"; 6 | import {IMarketConfigurationModule} from "@synthetixio/spot-market/contracts/interfaces/IMarketConfigurationModule.sol"; 7 | 8 | // solhint-disable-next-line no-empty-blocks 9 | interface ISpotMarketSystem is 10 | IAtomicOrderModule, 11 | ISpotMarketFactoryModule, 12 | IMarketConfigurationModule 13 | {} 14 | -------------------------------------------------------------------------------- /markets/perps-market/contracts/mocks/MockPyth.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {MockPyth as BaseMockPyth} from "@synthetixio/oracle-manager/contracts/mocks/pyth/MockPyth.sol"; 5 | 6 | /** 7 | * @title Mocked Pyth. 8 | * See oracle-manager/../MockPyth 9 | */ 10 | contract MockPyth is BaseMockPyth { 11 | // solhint-disable no-empty-blocks 12 | constructor( 13 | uint256 _validTimePeriod, 14 | uint256 _singleUpdateFeeInWei 15 | ) BaseMockPyth(_validTimePeriod, _singleUpdateFeeInWei) {} 16 | // solhint-enable no-empty-blocks 17 | } 18 | -------------------------------------------------------------------------------- /markets/perps-market/contracts/modules/AssociatedSystemsModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {AssociatedSystemsModule as BaseAssociatedSystemsModule} from "@synthetixio/core-modules/contracts/modules/AssociatedSystemsModule.sol"; 5 | 6 | /** 7 | * @title Module for connecting to other systems. 8 | * See core-modules/../AssociatedSystemsModule 9 | */ 10 | // solhint-disable-next-line no-empty-blocks 11 | contract AssociatedSystemsModule is BaseAssociatedSystemsModule {} 12 | -------------------------------------------------------------------------------- /markets/perps-market/contracts/modules/CoreModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {CoreModule as BaseCoreModule} from "@synthetixio/core-modules/contracts/modules/CoreModule.sol"; 5 | 6 | /** 7 | * @title Module that defines ownership and upgradability. 8 | * See core-modules/../CoreModule 9 | */ 10 | // solhint-disable-next-line no-empty-blocks 11 | contract CoreModule is BaseCoreModule { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /markets/perps-market/contracts/modules/FeatureFlagModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {FeatureFlagModule as BaseFeatureFlagModule} from "@synthetixio/core-modules/contracts/modules/FeatureFlagModule.sol"; 5 | 6 | /** 7 | * @title Module that allows disabling certain system features. 8 | * 9 | * Users will not be able to interact with certain functions associated to disabled features. 10 | */ 11 | // solhint-disable-next-line no-empty-blocks 12 | contract FeatureFlagModule is BaseFeatureFlagModule {} 13 | -------------------------------------------------------------------------------- /markets/perps-market/contracts/storage/Liquidation.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title Liquidation data used for determining max liquidation amounts 6 | */ 7 | library Liquidation { 8 | struct Data { 9 | /** 10 | * @dev Accumulated amount for this corresponding timestamp 11 | */ 12 | uint128 amount; 13 | /** 14 | * @dev timestamp of the accumulated liqudation amount 15 | */ 16 | uint256 timestamp; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /markets/perps-market/contracts/storage/MarketUpdate.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title MarketUpdateData 6 | */ 7 | library MarketUpdate { 8 | // this data struct returns the data required to emit a MarketUpdated event 9 | struct Data { 10 | uint128 marketId; 11 | uint128 interestRate; 12 | int256 skew; 13 | uint256 size; 14 | int256 currentFundingRate; 15 | int256 currentFundingVelocity; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /markets/perps-market/contracts/storage/OrderFee.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title Orders Fee data 6 | */ 7 | library OrderFee { 8 | struct Data { 9 | /** 10 | * @dev Maker fee. Applied when order (or partial order) is reducing skew. 11 | */ 12 | uint256 makerFee; 13 | /** 14 | * @dev Taker fee. Applied when order (or partial order) is increasing skew. 15 | */ 16 | uint256 takerFee; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /markets/perps-market/contracts/utils/Flags.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | library Flags { 5 | bytes32 public constant PERPS_SYSTEM = "perpsSystem"; 6 | bytes32 public constant CREATE_MARKET = "createMarket"; 7 | } 8 | -------------------------------------------------------------------------------- /markets/perps-market/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import commonConfig from '@synthetixio/common-config/hardhat.config'; 2 | 3 | import 'solidity-docgen'; 4 | import { templates } from '@synthetixio/docgen'; 5 | 6 | const config = { 7 | ...commonConfig, 8 | allowUnlimitedContractSize: true, 9 | docgen: { 10 | exclude: [ 11 | './generated', 12 | './interfaces/external', 13 | './mocks', 14 | './modules', 15 | './storage', 16 | './utils', 17 | './Mocks.sol', 18 | './Proxy.sol', 19 | ], 20 | templates, 21 | }, 22 | mocha: { 23 | timeout: 30_000, 24 | }, 25 | }; 26 | 27 | export default config; 28 | -------------------------------------------------------------------------------- /markets/perps-market/subgraph/.gitignore: -------------------------------------------------------------------------------- 1 | .bin/ 2 | tests/.bin/ 3 | tests/.latest.json 4 | subgraph.yaml 5 | deployments/ 6 | build/ 7 | -------------------------------------------------------------------------------- /markets/perps-market/subgraph/base-mainnet-andromeda/handleAccountCreated.ts: -------------------------------------------------------------------------------- 1 | import { AccountCreated } from './generated/PerpsMarketProxy/PerpsMarketProxy'; 2 | import { Account } from './generated/schema'; 3 | 4 | export function handleAccountCreated(event: AccountCreated): void { 5 | const id = event.params.accountId.toString(); 6 | 7 | const account = new Account(id); 8 | 9 | account.accountId = event.params.accountId; 10 | account.owner = event.params.owner.toHexString(); 11 | account.save(); 12 | } 13 | -------------------------------------------------------------------------------- /markets/perps-market/subgraph/base-mainnet-andromeda/handleFundingParametersSet.ts: -------------------------------------------------------------------------------- 1 | import { FundingParametersSet } from './generated/PerpsMarketProxy/PerpsMarketProxy'; 2 | import { Market } from './generated/schema'; 3 | 4 | export function handleFundingParametersSet(event: FundingParametersSet): void { 5 | const id = event.params.marketId.toString(); 6 | const market = Market.load(id); 7 | 8 | if (market) { 9 | market.maxFundingVelocity = event.params.maxFundingVelocity; 10 | market.skewScale = event.params.skewScale; 11 | market.save(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /markets/perps-market/subgraph/base-mainnet-andromeda/handleLiquidationParametersSet.ts: -------------------------------------------------------------------------------- 1 | import { LiquidationParametersSet } from './generated/PerpsMarketProxy/PerpsMarketProxy'; 2 | import { Market } from './generated/schema'; 3 | 4 | export function handleLiquidationParametersSet(event: LiquidationParametersSet): void { 5 | const id = event.params.marketId.toString(); 6 | const market = Market.load(id); 7 | 8 | if (market) { 9 | market.initialMarginRatioD18 = event.params.initialMarginRatioD18; 10 | market.maintenanceMarginRatioD18 = event.params.maintenanceMarginRatioD18; 11 | market.minimumInitialMarginRatioD18 = event.params.minimumInitialMarginRatioD18; 12 | market.flagRewardRatioD18 = event.params.flagRewardRatioD18; 13 | market.minimumPositionMargin = event.params.minimumPositionMargin; 14 | market.save(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /markets/perps-market/subgraph/base-mainnet-andromeda/handleLockedOiRatioSet.ts: -------------------------------------------------------------------------------- 1 | import { LockedOiRatioSet } from './generated/PerpsMarketProxy/PerpsMarketProxy'; 2 | import { Market } from './generated/schema'; 3 | 4 | export function handleLockedOiRatioSet(event: LockedOiRatioSet): void { 5 | const id = event.params.marketId.toString(); 6 | const market = Market.load(id); 7 | 8 | if (market) { 9 | market.lockedOiPercent = event.params.lockedOiRatioD18; 10 | market.save(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /markets/perps-market/subgraph/base-mainnet-andromeda/handleMarketCreated.ts: -------------------------------------------------------------------------------- 1 | import { MarketCreated } from './generated/PerpsMarketProxy/PerpsMarketProxy'; 2 | import { Market } from './generated/schema'; 3 | 4 | export function handleMarketCreated(event: MarketCreated): void { 5 | const id = event.params.perpsMarketId.toString(); 6 | const market = new Market(id); 7 | 8 | market.perpsMarketId = event.params.perpsMarketId; 9 | market.marketName = event.params.marketName; 10 | market.marketSymbol = event.params.marketSymbol; 11 | market.save(); 12 | } 13 | -------------------------------------------------------------------------------- /markets/perps-market/subgraph/base-mainnet-andromeda/handleMarketPriceDataUpdated.ts: -------------------------------------------------------------------------------- 1 | import { MarketPriceDataUpdated } from './generated/PerpsMarketProxy/PerpsMarketProxy'; 2 | import { Market } from './generated/schema'; 3 | 4 | export function handleMarketPriceDataUpdated(event: MarketPriceDataUpdated): void { 5 | const id = event.params.marketId.toString(); 6 | const market = Market.load(id); 7 | 8 | if (market) { 9 | market.feedId = event.params.feedId; 10 | market.save(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /markets/perps-market/subgraph/base-mainnet-andromeda/handleMaxLiquidationParametersSet.ts: -------------------------------------------------------------------------------- 1 | import { MaxLiquidationParametersSet } from './generated/PerpsMarketProxy/PerpsMarketProxy'; 2 | import { Market } from './generated/schema'; 3 | 4 | export function handleMaxLiquidationParametersSet(event: MaxLiquidationParametersSet): void { 5 | const id = event.params.marketId.toString(); 6 | const market = Market.load(id); 7 | 8 | if (market) { 9 | market.maxLiquidationLimitAccumulationMultiplier = 10 | event.params.maxLiquidationLimitAccumulationMultiplier; 11 | market.maxSecondsInLiquidationWindow = event.params.maxSecondsInLiquidationWindow; 12 | market.maxLiquidationPd = event.params.maxLiquidationPd; 13 | market.endorsedLiquidator = event.params.endorsedLiquidator.toHexString(); 14 | 15 | market.save(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /markets/perps-market/subgraph/base-mainnet-andromeda/handleOrderFeesSet.ts: -------------------------------------------------------------------------------- 1 | import { OrderFeesSet } from './generated/PerpsMarketProxy/PerpsMarketProxy'; 2 | import { Market } from './generated/schema'; 3 | 4 | export function handleOrderFeesSet(event: OrderFeesSet): void { 5 | const id = event.params.marketId.toString(); 6 | const market = Market.load(id); 7 | 8 | if (market) { 9 | market.makerFee = event.params.makerFeeRatio; 10 | market.takerFee = event.params.takerFeeRatio; 11 | market.save(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /markets/perps-market/subgraph/base-mainnet-andromeda/handleReferrerShareUpdated.ts: -------------------------------------------------------------------------------- 1 | import { ReferrerShareUpdated } from './generated/PerpsMarketProxy/PerpsMarketProxy'; 2 | import { ReferrerShare } from './generated/schema'; 3 | 4 | export function handleReferrerShareUpdated(event: ReferrerShareUpdated): void { 5 | const id = event.params.referrer.toHexString(); 6 | 7 | let referrerShare = ReferrerShare.load(id); 8 | 9 | if (!referrerShare) { 10 | referrerShare = new ReferrerShare(id); 11 | } 12 | 13 | referrerShare.referrer = event.params.referrer.toHexString(); 14 | referrerShare.shareRatioD18 = event.params.shareRatioD18; 15 | referrerShare.save(); 16 | } 17 | -------------------------------------------------------------------------------- /markets/perps-market/subgraph/base-mainnet-andromeda/index.ts: -------------------------------------------------------------------------------- 1 | export * from './handleAccountCreated'; 2 | export * from './handleCollateralModified'; 3 | export * from './handleFundingParametersSet'; 4 | export * from './handleLiquidationParametersSet'; 5 | export * from './handleLockedOiRatioSet'; 6 | export * from './handleMarketCreated'; 7 | export * from './handleMarketPriceDataUpdated'; 8 | export * from './handleMarketUpdated'; 9 | export * from './handleMaxLiquidationParametersSet'; 10 | export * from './handleOrderCommitted'; 11 | export * from './handleOrderFeesSet'; 12 | export * from './handleOrderSettled'; 13 | export * from './handlePositionLiquidated'; 14 | export * from './handlePreviousOrderExpired'; 15 | export * from './handleReferrerShareUpdated'; 16 | export * from './handleSettlementStrategyAdded'; 17 | export * from './handleSettlementStrategySet'; 18 | -------------------------------------------------------------------------------- /markets/perps-market/subgraph/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | export CANNON_IPFS_URL="https://ipfs.synthetix.io" 5 | 6 | build() { 7 | namespace=$1 8 | 9 | echo 10 | echo 11 | echo 12 | echo '>' graph build "subgraph.$namespace.yaml" --output-dir "./build/$namespace" 13 | yarn graph build "subgraph.$namespace.yaml" --output-dir "./build/$namespace" 14 | yarn prettier --write "subgraph.$namespace.yaml" 15 | } 16 | 17 | build base-mainnet-andromeda 18 | build base-sepolia-andromeda 19 | -------------------------------------------------------------------------------- /markets/perps-market/subgraph/matchstick.yaml: -------------------------------------------------------------------------------- 1 | testFolder: tests/ 2 | libsFolder: ../../../node_modules/ 3 | manifestPath: ./subgraph.base-mainnet-andromeda.yaml 4 | -------------------------------------------------------------------------------- /markets/perps-market/subgraph/tests/handleAccountCreated.ts: -------------------------------------------------------------------------------- 1 | import { assert, log } from 'matchstick-as'; 2 | import { handleAccountCreated } from '../base-mainnet-andromeda'; 3 | import { createAccountCreatedEvent } from './event-factories/createAccountCreatedEvent'; 4 | 5 | export default function test(): void { 6 | assert.entityCount('Account', 0); 7 | 8 | log.info('Should create a new record for the account', []); 9 | const owner1 = '0x4200000000000000000000000000000000000000'; 10 | handleAccountCreated(createAccountCreatedEvent(1, owner1, 10_000, 10)); 11 | assert.entityCount('Account', 1); 12 | assert.fieldEquals('Account', '1', 'id', '1'); 13 | assert.fieldEquals('Account', '1', 'accountId', '1'); 14 | assert.fieldEquals('Account', '1', 'owner', owner1); 15 | } 16 | -------------------------------------------------------------------------------- /markets/perps-market/subgraph/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@graphprotocol/graph-ts/types/tsconfig.base.json", 3 | "include": ["src"] 4 | } 5 | -------------------------------------------------------------------------------- /markets/perps-market/test/integration/Market/CreateMarket.failures.test.ts: -------------------------------------------------------------------------------- 1 | import { bootstrap } from '../bootstrap'; 2 | import assertRevert from '@synthetixio/core-utils/utils/assertions/assert-revert'; 3 | 4 | describe('Create Market test - not initialized failure', () => { 5 | const name = 'Ether', 6 | token = 'snxETH'; 7 | 8 | const { systems, owner } = bootstrap(); 9 | 10 | it('reverts when trying to create a market', async () => { 11 | await assertRevert( 12 | systems().PerpsMarket.connect(owner()).createMarket(1, name, token), 13 | 'PerpsMarketNotInitialized' 14 | ); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /markets/perps-market/test/integration/bootstrap/index.ts: -------------------------------------------------------------------------------- 1 | export * from './bootstrap'; 2 | export * from './bootstrapPerpsMarkets'; 3 | export * from './bootstrapTraders'; 4 | export * from './createKeeperCostNode'; 5 | export * from './createRewardsDistributor'; 6 | -------------------------------------------------------------------------------- /markets/perps-market/test/integration/helpers/createAccountAndPosition.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'ethers'; 2 | import { OpenPositionData, openPosition } from '.'; 3 | 4 | export const createAccountAndOpenPosition = async ( 5 | data: OpenPositionData & { collateral: ethers.BigNumber } 6 | ) => { 7 | await data.systems().PerpsMarket.connect(data.trader)['createAccount(uint128)'](data.accountId); 8 | await data 9 | .systems() 10 | .PerpsMarket.connect(data.trader) 11 | .modifyCollateral(data.accountId, 0, data.collateral); 12 | await openPosition(data); 13 | }; 14 | -------------------------------------------------------------------------------- /markets/perps-market/test/integration/helpers/funding-calcs.ts: -------------------------------------------------------------------------------- 1 | import Wei, { wei } from '@synthetixio/wei'; 2 | 3 | export function calcCurrentFundingVelocity({ 4 | skew, 5 | skewScale, 6 | maxFundingVelocity, 7 | }: { 8 | skew: Wei; 9 | skewScale: Wei; 10 | maxFundingVelocity: Wei; 11 | }) { 12 | // Avoid a panic due to div by zero. Return 0 immediately. 13 | if (skewScale.eq(0)) { 14 | return wei(0); 15 | } 16 | 17 | // Ensures the proportionalSkew is between -1 and 1. 18 | const pSkew = wei(skew).div(skewScale); 19 | const pSkewBounded = Wei.max(Wei.min(pSkew, wei(1)), wei(-1)); 20 | 21 | return pSkewBounded.mul(maxFundingVelocity); 22 | } 23 | -------------------------------------------------------------------------------- /markets/perps-market/test/integration/helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './settleHelper'; 2 | export * from './collateralHelper'; 3 | export * from './openPosition'; 4 | export * from './fillPrice'; 5 | export * from './computeFees'; 6 | export * from './requiredMargins'; 7 | export * from './createAccountAndPosition'; 8 | export * from './interestRate'; 9 | -------------------------------------------------------------------------------- /markets/perps-market/test/integration/helpers/interestRate.ts: -------------------------------------------------------------------------------- 1 | import Wei from '@synthetixio/wei'; 2 | 3 | type InterestRateParams = { 4 | lowUtilGradient: Wei; 5 | gradientBreakpoint: Wei; 6 | highUtilGradient: Wei; 7 | }; 8 | 9 | export const calculateInterestRate = (utilRate: Wei, interestRateParams: InterestRateParams) => { 10 | return ( 11 | utilRate.lt(interestRateParams.gradientBreakpoint) 12 | ? utilRate.mul(interestRateParams.lowUtilGradient) 13 | : interestRateParams.lowUtilGradient 14 | .mul(interestRateParams.gradientBreakpoint) 15 | .add( 16 | utilRate 17 | .sub(interestRateParams.gradientBreakpoint) 18 | .mul(interestRateParams.highUtilGradient) 19 | ) 20 | ).mul(100); 21 | }; 22 | -------------------------------------------------------------------------------- /markets/perps-market/test/integration/helpers/maxSize.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Synthetixio/synthetix-v3/d795f6dcdcbc644f8dfbc684903c56f9b6e751e2/markets/perps-market/test/integration/helpers/maxSize.ts -------------------------------------------------------------------------------- /markets/perps-market/test/integration/helpers/settleHelper.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'ethers'; 2 | import { Systems } from '../bootstrap'; 3 | 4 | export type SettleOrderData = { 5 | systems: () => Systems; 6 | keeper: ethers.Signer; 7 | accountId: number; 8 | offChainPrice: ethers.BigNumberish; 9 | skipSettingPrice?: boolean; 10 | }; 11 | 12 | export const settleOrder = async ({ 13 | systems, 14 | keeper, 15 | accountId, 16 | offChainPrice, 17 | skipSettingPrice, 18 | }: SettleOrderData): Promise => { 19 | // set Pyth setBenchmarkPrice 20 | if (!skipSettingPrice) { 21 | await systems().MockPythERC7412Wrapper.setBenchmarkPrice(offChainPrice); 22 | } 23 | // settle 24 | const tx = await systems().PerpsMarket.connect(keeper).settleOrder(accountId); 25 | return tx; 26 | }; 27 | -------------------------------------------------------------------------------- /markets/spot-market/.gitignore: -------------------------------------------------------------------------------- 1 | # generated test modules 2 | contracts/modules/test 3 | contracts/generated 4 | 5 | # generated routers 6 | contracts/routers 7 | -------------------------------------------------------------------------------- /markets/spot-market/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require('@synthetixio/common-config/.solcover.js'), 3 | skipFiles: ['mocks', 'Mocks.sol'], 4 | }; 5 | -------------------------------------------------------------------------------- /markets/spot-market/contracts/.gitignore: -------------------------------------------------------------------------------- 1 | Router.sol -------------------------------------------------------------------------------- /markets/spot-market/contracts/Mocks.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/oracle-manager/contracts/mocks/MockExternalNode.sol"; 5 | import "@synthetixio/oracle-manager/contracts/mocks/MockPythExternalNode.sol"; 6 | -------------------------------------------------------------------------------- /markets/spot-market/contracts/Proxy.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {UUPSProxyWithOwner} from "@synthetixio/core-contracts/contracts/proxy/UUPSProxyWithOwner.sol"; 5 | 6 | contract Proxy is UUPSProxyWithOwner { 7 | constructor( 8 | address firstImplementation, 9 | address initialOwner 10 | ) 11 | UUPSProxyWithOwner(firstImplementation, initialOwner) 12 | // solhint-disable-next-line no-empty-blocks 13 | { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /markets/spot-market/contracts/interfaces/ISynthTokenModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {IDecayTokenModule} from "@synthetixio/core-modules/contracts/interfaces/IDecayTokenModule.sol"; 5 | 6 | /** 7 | * @title Module for market synth tokens 8 | */ 9 | // solhint-disable-next-line no-empty-blocks 10 | interface ISynthTokenModule is IDecayTokenModule {} 11 | -------------------------------------------------------------------------------- /markets/spot-market/contracts/interfaces/external/IChainlinkVerifier.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | interface IChainlinkVerifier { 5 | function verify(bytes memory chainlinkBlob) external returns (bytes memory verifierResponse); 6 | } 7 | -------------------------------------------------------------------------------- /markets/spot-market/contracts/interfaces/external/IPythERC7412Wrapper.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | interface IPythERC7412Wrapper { 5 | error OracleDataRequired(address oracleContract, bytes oracleQuery); 6 | 7 | function getBenchmarkPrice( 8 | bytes32 priceId, 9 | uint64 requestedTime 10 | ) external view returns (int256); 11 | 12 | function getLatestPrice( 13 | bytes32 priceId, 14 | uint256 stalenessTolerance 15 | ) external view returns (int256); 16 | 17 | function fulfillOracleQuery(bytes memory signedOffchainData) external payable; 18 | } 19 | -------------------------------------------------------------------------------- /markets/spot-market/contracts/interfaces/external/ISynthetixSystem.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/core-modules/contracts/interfaces/IAssociatedSystemsModule.sol"; 5 | import "@synthetixio/main/contracts/interfaces/IMarketManagerModule.sol"; 6 | import "@synthetixio/main/contracts/interfaces/IMarketCollateralModule.sol"; 7 | import "@synthetixio/main/contracts/interfaces/IUtilsModule.sol"; 8 | 9 | // solhint-disable no-empty-blocks 10 | interface ISynthetixSystem is 11 | IAssociatedSystemsModule, 12 | IMarketCollateralModule, 13 | IMarketManagerModule, 14 | IUtilsModule 15 | {} 16 | // solhint-enable no-empty-blocks 17 | -------------------------------------------------------------------------------- /markets/spot-market/contracts/mocks/CollateralMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {CollateralMock} from "@synthetixio/main/contracts/mocks/CollateralMock.sol"; 5 | -------------------------------------------------------------------------------- /markets/spot-market/contracts/mocks/ERC20Mock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {ERC20Mock} from "@synthetixio/core-contracts/contracts/mocks/token/ERC20Mock.sol"; 5 | -------------------------------------------------------------------------------- /markets/spot-market/contracts/mocks/MockPythERC7412Wrapper.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {MockPythERC7412Wrapper as BaseMockPythERC7412Wrapper} from "@synthetixio/perps-market/contracts/mocks/MockPythERC7412Wrapper.sol"; 5 | 6 | contract MockPythERC7412Wrapper is BaseMockPythERC7412Wrapper {} 7 | -------------------------------------------------------------------------------- /markets/spot-market/contracts/modules/CoreModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {CoreModule as BaseCoreModule} from "@synthetixio/core-modules/contracts/modules/CoreModule.sol"; 5 | 6 | // solhint-disable-next-line no-empty-blocks 7 | contract CoreModule is BaseCoreModule { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /markets/spot-market/contracts/modules/FeatureFlagModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {FeatureFlagModule as BaseFeatureFlagModule} from "@synthetixio/core-modules/contracts/modules/FeatureFlagModule.sol"; 5 | 6 | /** 7 | * @title Module that allows disabling certain system features. 8 | * 9 | * Users will not be able to interact with certain functions associated to disabled features. 10 | */ 11 | // solhint-disable-next-line no-empty-blocks 12 | contract FeatureFlagModule is BaseFeatureFlagModule {} 13 | -------------------------------------------------------------------------------- /markets/spot-market/contracts/modules/token/SynthTokenModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {DecayTokenModule} from "@synthetixio/core-modules/contracts/modules/DecayTokenModule.sol"; 5 | 6 | // solhint-disable-next-line no-empty-blocks 7 | contract SynthTokenModule is DecayTokenModule {} 8 | -------------------------------------------------------------------------------- /markets/spot-market/contracts/storage/OrderFees.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {SafeCastU256} from "@synthetixio/core-contracts/contracts/utils/SafeCast.sol"; 5 | 6 | /** 7 | * @notice A convenience library that includes a Data struct which is used to track fees across different trade types 8 | */ 9 | library OrderFees { 10 | using SafeCastU256 for uint256; 11 | 12 | struct Data { 13 | uint256 fixedFees; 14 | uint256 utilizationFees; 15 | int256 skewFees; 16 | int256 wrapperFees; 17 | } 18 | 19 | function total(Data memory self) internal pure returns (int256 amount) { 20 | return 21 | self.fixedFees.toInt() + 22 | self.utilizationFees.toInt() + 23 | self.skewFees + 24 | self.wrapperFees; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /markets/spot-market/contracts/utils/Flags.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | library Flags { 5 | string public constant WRAPPER_ENABLED = "wrapperEnabled"; 6 | string public constant ATOMIC_ORDERS_ENABLED = "atomicOrdersEnabled"; 7 | bytes32 public constant SPOT_MARKET_ENABLED = "spotMarketEnabled"; 8 | } 9 | -------------------------------------------------------------------------------- /markets/spot-market/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import commonConfig from '@synthetixio/common-config/hardhat.config'; 2 | 3 | import 'solidity-docgen'; 4 | import { templates } from '@synthetixio/docgen'; 5 | 6 | const config = { 7 | ...commonConfig, 8 | allowUnlimitedContractSize: true, 9 | docgen: { 10 | exclude: [ 11 | './generated', 12 | './interfaces/external', 13 | './mocks', 14 | './modules', 15 | './storage', 16 | './utils', 17 | './Mocks.sol', 18 | './Proxy.sol', 19 | ], 20 | templates, 21 | }, 22 | warnings: { 23 | 'contracts/mocks/**/*': { 24 | default: 'off', 25 | }, 26 | }, 27 | mocha: { 28 | timeout: 30_000, 29 | }, 30 | }; 31 | 32 | export default config; 33 | -------------------------------------------------------------------------------- /markets/spot-market/subgraph/.gitignore: -------------------------------------------------------------------------------- 1 | .bin/ 2 | tests/.bin/ 3 | tests/.latest.json 4 | subgraph.yaml 5 | deployments/ 6 | build/ 7 | -------------------------------------------------------------------------------- /markets/spot-market/subgraph/base-mainnet-andromeda/index.ts: -------------------------------------------------------------------------------- 1 | export * from '../optimism-mainnet/handleOrderCancelled'; 2 | export * from '../optimism-mainnet/handleOrderCommitted'; 3 | export * from '../optimism-mainnet/handleOrderSettled'; 4 | export * from '../optimism-mainnet/handleSettlementStrategyAdded'; 5 | export * from '../optimism-mainnet/handleSettlementStrategySet'; 6 | export * from '../optimism-mainnet/handleSynthPriceDataUpdated'; 7 | export * from '../optimism-mainnet/handleSynthUnwrapped'; 8 | export * from '../optimism-mainnet/handleSynthWrapped'; 9 | export * from '../optimism-mainnet/handleWrapperSet'; 10 | -------------------------------------------------------------------------------- /markets/spot-market/subgraph/base-sepolia-andromeda/index.ts: -------------------------------------------------------------------------------- 1 | export * from '../optimism-mainnet/handleOrderCancelled'; 2 | export * from '../optimism-mainnet/handleOrderCommitted'; 3 | export * from '../optimism-mainnet/handleOrderSettled'; 4 | export * from '../optimism-mainnet/handleSettlementStrategyAdded'; 5 | export * from '../optimism-mainnet/handleSettlementStrategySet'; 6 | export * from '../optimism-mainnet/handleSynthPriceDataUpdated'; 7 | export * from '../optimism-mainnet/handleSynthUnwrapped'; 8 | export * from '../optimism-mainnet/handleSynthWrapped'; 9 | export * from '../optimism-mainnet/handleWrapperSet'; 10 | -------------------------------------------------------------------------------- /markets/spot-market/subgraph/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | export CANNON_IPFS_URL="https://ipfs.synthetix.io" 5 | 6 | build() { 7 | namespace=$1 8 | 9 | echo 10 | echo 11 | echo 12 | echo '>' graph build "subgraph.$namespace.yaml" --output-dir "./build/$namespace" 13 | yarn graph build "subgraph.$namespace.yaml" --output-dir "./build/$namespace" 14 | yarn prettier --write "subgraph.$namespace.yaml" 15 | } 16 | 17 | build base-mainnet-andromeda 18 | build base-sepolia-andromeda 19 | -------------------------------------------------------------------------------- /markets/spot-market/subgraph/matchstick.yaml: -------------------------------------------------------------------------------- 1 | testFolder: tests/ 2 | libsFolder: ../../../node_modules/ 3 | manifestPath: ./subgraph.optimism-mainnet.yaml 4 | -------------------------------------------------------------------------------- /markets/spot-market/subgraph/optimism-mainnet/handleSettlementStrategyAdded.ts: -------------------------------------------------------------------------------- 1 | import { SettlementStrategyAdded } from './generated/SpotMarketProxy/SpotMarketProxy'; 2 | import { SettlementStrategy } from './generated/schema'; 3 | 4 | export function handleSettlementStrategyAdded(event: SettlementStrategyAdded): void { 5 | let id = event.params.strategyId.toString(); 6 | let strategy = new SettlementStrategy(id); 7 | 8 | strategy.marketId = event.params.synthMarketId; 9 | strategy.settlementStrategyId = event.params.strategyId; 10 | 11 | // TODO: this value MUST be present, 12 | // but impossible to get from the event data. 13 | // tis is a WRONG made up value 14 | strategy.disabled = true; 15 | 16 | strategy.save(); 17 | } 18 | -------------------------------------------------------------------------------- /markets/spot-market/subgraph/optimism-mainnet/handleSynthPriceDataUpdated.ts: -------------------------------------------------------------------------------- 1 | import { SynthPriceDataUpdated } from './generated/SpotMarketProxy/SpotMarketProxy'; 2 | import { MarketInfo } from './generated/schema'; 3 | 4 | export function handleSynthPriceDataUpdated(event: SynthPriceDataUpdated): void { 5 | let id = event.params.synthMarketId.toString(); 6 | let marketInfo = MarketInfo.load(id); 7 | 8 | if (!marketInfo) { 9 | marketInfo = new MarketInfo(id); 10 | } 11 | 12 | marketInfo.marketId = event.params.synthMarketId; 13 | marketInfo.sellFeedId = event.params.sellFeedId; 14 | marketInfo.buyFeedId = event.params.buyFeedId; 15 | marketInfo.save(); 16 | } 17 | -------------------------------------------------------------------------------- /markets/spot-market/subgraph/optimism-mainnet/handleSynthUnwrapped.ts: -------------------------------------------------------------------------------- 1 | import { SynthUnwrapped } from './generated/SpotMarketProxy/SpotMarketProxy'; 2 | import { WrapSynth } from './generated/schema'; 3 | 4 | export function handleSynthUnwrapped(event: SynthUnwrapped): void { 5 | let id = event.transaction.hash.toHexString() + '/' + event.logIndex.toString(); 6 | let synth = new WrapSynth(id); 7 | 8 | synth.marketId = event.params.synthMarketId; 9 | synth.amount = event.params.amountUnwrapped; 10 | synth.collectedFees = event.params.feesCollected; 11 | synth.wrapperFees = event.params.fees.wrapperFees; 12 | synth.type = 'Unwrapped'; 13 | synth.block = event.block.number; 14 | synth.timestamp = event.block.timestamp; 15 | 16 | synth.save(); 17 | } 18 | -------------------------------------------------------------------------------- /markets/spot-market/subgraph/optimism-mainnet/handleSynthWrapped.ts: -------------------------------------------------------------------------------- 1 | import { SynthWrapped } from './generated/SpotMarketProxy/SpotMarketProxy'; 2 | import { WrapSynth } from './generated/schema'; 3 | 4 | export function handleSynthWrapped(event: SynthWrapped): void { 5 | let id = event.transaction.hash.toHexString() + '/' + event.logIndex.toString(); 6 | let synth = new WrapSynth(id); 7 | 8 | synth.marketId = event.params.synthMarketId; 9 | synth.amount = event.params.amountWrapped; 10 | synth.collectedFees = event.params.feesCollected; 11 | synth.wrapperFees = event.params.fees.wrapperFees; 12 | synth.type = 'Wrapped'; 13 | synth.block = event.block.number; 14 | synth.timestamp = event.block.timestamp; 15 | 16 | synth.save(); 17 | } 18 | -------------------------------------------------------------------------------- /markets/spot-market/subgraph/optimism-mainnet/handleWrapperSet.ts: -------------------------------------------------------------------------------- 1 | import { WrapperSet } from './generated/SpotMarketProxy/SpotMarketProxy'; 2 | import { Wrapper } from './generated/schema'; 3 | 4 | export function handleWrapperSet(event: WrapperSet): void { 5 | let id = event.params.synthMarketId.toString(); 6 | let wrapperConfig = Wrapper.load(id); 7 | 8 | if (!wrapperConfig) { 9 | wrapperConfig = new Wrapper(id); 10 | } 11 | 12 | wrapperConfig.wrapCollateralType = event.params.wrapCollateralType.toHexString(); 13 | wrapperConfig.maxWrappableAmount = event.params.maxWrappableAmount; 14 | wrapperConfig.marketId = event.params.synthMarketId; 15 | wrapperConfig.save(); 16 | } 17 | -------------------------------------------------------------------------------- /markets/spot-market/subgraph/optimism-mainnet/index.ts: -------------------------------------------------------------------------------- 1 | export * from './handleOrderCancelled'; 2 | export * from './handleOrderCommitted'; 3 | export * from './handleOrderSettled'; 4 | export * from './handleSettlementStrategyAdded'; 5 | export * from './handleSettlementStrategySet'; 6 | export * from './handleSynthPriceDataUpdated'; 7 | export * from './handleSynthUnwrapped'; 8 | export * from './handleSynthWrapped'; 9 | export * from './handleWrapperSet'; 10 | -------------------------------------------------------------------------------- /markets/spot-market/subgraph/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@graphprotocol/graph-ts/types/tsconfig.base.json", 3 | "include": ["src"] 4 | } 5 | -------------------------------------------------------------------------------- /markets/spot-market/test/common/index.ts: -------------------------------------------------------------------------------- 1 | export * from './bootstrapSynthMarkets'; 2 | -------------------------------------------------------------------------------- /markets/treasury-market/contracts/InitialModuleBundle.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/core-modules/contracts/modules/OwnerModule.sol"; 5 | import "@synthetixio/core-modules/contracts/modules/UpgradeModule.sol"; 6 | 7 | // The below contract is only used during initialization as a kernel for the first release which the system can be upgraded onto. 8 | // Subsequent upgrades will not need this module bundle 9 | // In the future on live networks, we may want to find some way to hardcode the owner address here to prevent grieving 10 | 11 | // solhint-disable-next-line no-empty-blocks 12 | contract InitialModuleBundle is OwnerModule, UpgradeModule {} 13 | -------------------------------------------------------------------------------- /markets/treasury-market/contracts/SynthetixTreasuryProxy.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {UUPSProxyWithOwner} from "@synthetixio/core-contracts/contracts/proxy/UUPSProxyWithOwner.sol"; 5 | 6 | /** 7 | * This is the the proxy for the Synthetix Treasury Market, a market for Synthetix v3. 8 | * For best results, you can interact with this contract, view its full source code in context and other implementation details via Cannon: 9 | * https://usecannon.com/packages/synthetix-treasury-market 10 | */ 11 | contract SynthetixTreasuryProxy is UUPSProxyWithOwner { 12 | // solhint-disable-next-line no-empty-blocks 13 | constructor( 14 | address firstImplementation, 15 | address initialOwner 16 | ) UUPSProxyWithOwner(firstImplementation, initialOwner) {} 17 | } 18 | -------------------------------------------------------------------------------- /markets/treasury-market/contracts/interfaces/ITreasuryStakingRewards.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | // https://docs.synthetix.io/contracts/source/interfaces/istakingrewards 5 | interface ITreasuryStakingRewards { 6 | function balanceOf(uint128 accountId) external view returns (uint256); 7 | function totalDeposited() external view returns (uint256); 8 | function deposit(uint128 accountId, uint256 amount) external; 9 | } 10 | -------------------------------------------------------------------------------- /markets/treasury-market/foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | ast = true 3 | solc_version = "0.8.27" 4 | allow_paths = ["../../"] 5 | optimizer = true 6 | -------------------------------------------------------------------------------- /markets/treasury-market/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import commonConfig from '@synthetixio/common-config/hardhat.config'; 2 | 3 | import 'solidity-docgen'; 4 | import { templates } from '@synthetixio/docgen'; 5 | 6 | const config = { 7 | ...commonConfig, 8 | docgen: { 9 | exclude: ['./generated', './interfaces/external', './InitialModuleBundle.sol'], 10 | templates, 11 | }, 12 | }; 13 | 14 | export default config; 15 | -------------------------------------------------------------------------------- /markets/treasury-market/remappings.txt: -------------------------------------------------------------------------------- 1 | @synthetixio/core-contracts=../../utils/core-contracts 2 | @synthetixio/core-modules=../../utils/core-modules 3 | @synthetixio/main=../../protocol/synthetix 4 | @synthetixio/oracle-manager=../../protocol/oracle-manager 5 | forge-std=../../node_modules/forge-std/src 6 | -------------------------------------------------------------------------------- /markets/treasury-market/storage.dump.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /protocol/governance/.gitignore: -------------------------------------------------------------------------------- 1 | contracts/generated 2 | test/generated 3 | -------------------------------------------------------------------------------- /protocol/governance/.npmrc: -------------------------------------------------------------------------------- 1 | save-exact=true 2 | save-prefix='' 3 | -------------------------------------------------------------------------------- /protocol/governance/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require('@synthetixio/common-config/.solcover.js'), 3 | skipFiles: ['mocks', 'generated'], 4 | }; 5 | -------------------------------------------------------------------------------- /protocol/governance/cannonfile.snapshot-record-mock.toml: -------------------------------------------------------------------------------- 1 | name = "synthetix-snapshot-record-mock" 2 | description = "On-chain voting for synthetix councils - Snapshot record mock auxiliary contract" 3 | version = "<%= package.version %>" 4 | 5 | [setting.salt] 6 | defaultValue = "snapshot-record-mock" 7 | 8 | [contract.SnapshotRecordMock] 9 | artifact = "contracts/mocks/SnapshotRecordMock.sol:SnapshotRecordMock" 10 | salt = "<%= settings.salt %>" 11 | create2 = true 12 | -------------------------------------------------------------------------------- /protocol/governance/contracts/Proxy.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {UUPSProxyWithOwner} from "@synthetixio/core-contracts/contracts/proxy/UUPSProxyWithOwner.sol"; 5 | 6 | contract Proxy is UUPSProxyWithOwner { 7 | constructor( 8 | address firstImplementation, 9 | address initialOwner 10 | ) UUPSProxyWithOwner(firstImplementation, initialOwner) {} // solhint-disable-line no-empty-blocks 11 | } 12 | -------------------------------------------------------------------------------- /protocol/governance/contracts/interfaces/ICouncilTokenModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {INftModule} from "@synthetixio/core-modules/contracts/interfaces/INftModule.sol"; 5 | 6 | /** 7 | * @title Module with custom NFT logic for the account token. 8 | */ 9 | // solhint-disable-next-line no-empty-blocks 10 | interface ICouncilTokenModule is INftModule {} 11 | -------------------------------------------------------------------------------- /protocol/governance/contracts/interfaces/IDebtShare.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | interface IDebtShare { 5 | function balanceOfOnPeriod(address account, uint256 periodId) external view returns (uint256); 6 | } 7 | -------------------------------------------------------------------------------- /protocol/governance/contracts/interfaces/external/ISnapshotRecord.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | interface ISnapshotRecord { 5 | function currentPeriodId() external view returns (uint128); 6 | 7 | function balanceOfOnPeriod(address account, uint256 periodId) external view returns (uint256); 8 | 9 | function totalSupplyOnPeriod(uint256 periodId) external view returns (uint256); 10 | 11 | function takeSnapshot(uint128 id) external; 12 | } 13 | -------------------------------------------------------------------------------- /protocol/governance/contracts/mocks/CouncilMemberMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {ElectionCredentials} from "../submodules/election/ElectionCredentials.sol"; 5 | 6 | /// @dev Helper functions to test council members functionality 7 | contract CouncilMemberMock is ElectionCredentials { 8 | function addCouncilMembersMock(address[] memory membersToAdd, uint256 epochIndex) external { 9 | _addCouncilMembers(membersToAdd, epochIndex); 10 | } 11 | 12 | function removeAllCouncilMembersMock(uint256 epochIndex) external { 13 | _removeAllCouncilMembers(epochIndex); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /protocol/governance/contracts/mocks/WormholeMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import {WormholeMock as WormholeMockBase} from "@synthetixio/core-modules/contracts/mocks/WormholeMock.sol"; 5 | 6 | // solhint-disable-next-line no-empty-blocks 7 | contract WormholeMock is WormholeMockBase { 8 | constructor(uint256 chainId) WormholeMockBase(chainId) {} 9 | } 10 | -------------------------------------------------------------------------------- /protocol/governance/contracts/mocks/WormholeRelayerMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import {WormholeRelayerMock as WormholeRelayerMockBase} from "@synthetixio/core-modules/contracts/mocks/WormholeRelayerMock.sol"; 5 | 6 | // solhint-disable-next-line no-empty-blocks 7 | contract WormholeRelayerMock is WormholeRelayerMockBase { 8 | constructor(address _wormhole) WormholeRelayerMockBase(_wormhole) {} 9 | } 10 | -------------------------------------------------------------------------------- /protocol/governance/contracts/modules/core/AssociatedSystemsModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {AssociatedSystemsModule as BaseAssociatedSystemsModule} from "@synthetixio/core-modules/contracts/modules/AssociatedSystemsModule.sol"; 5 | 6 | /** 7 | * @title Module for connecting to other systems. 8 | * See core-modules/../AssociatedSystemsModule 9 | */ 10 | // solhint-disable-next-line no-empty-blocks 11 | contract AssociatedSystemsModule is BaseAssociatedSystemsModule {} 12 | -------------------------------------------------------------------------------- /protocol/governance/contracts/modules/core/InitialModuleBundle.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {OwnerModule} from "@synthetixio/core-modules/contracts/modules/OwnerModule.sol"; 5 | import {UpgradeModule} from "@synthetixio/core-modules/contracts/modules/UpgradeModule.sol"; 6 | 7 | // solhint-disable-next-line no-empty-blocks 8 | contract InitialModuleBundle is OwnerModule, UpgradeModule { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /protocol/governance/contracts/modules/core/WormholeCrossChainModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {WormholeCrossChainModule as BaseCrossChainModule} from "@synthetixio/core-modules/contracts/modules/WormholeCrossChainModule.sol"; 5 | 6 | /** 7 | * @title Module that handles anything related to cross-chain. 8 | */ 9 | // solhint-disable-next-line no-empty-blocks 10 | contract WormholeCrossChainModule is BaseCrossChainModule {} 11 | -------------------------------------------------------------------------------- /protocol/governance/contracts/modules/council-nft/CouncilTokenModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {NftModule} from "@synthetixio/core-modules/contracts/modules/NftModule.sol"; 5 | import {ICouncilTokenModule} from "../../interfaces/ICouncilTokenModule.sol"; 6 | 7 | /* solhint-disable no-empty-blocks */ 8 | /** 9 | * @title Module with custom NFT logic for the account token. 10 | * @dev See IAccountTokenModule. 11 | */ 12 | // solhint-disable-next-line no-empty-blocks 13 | contract CouncilTokenModule is ICouncilTokenModule, NftModule { 14 | error NotImplemented(); 15 | 16 | function _transfer(address, address, uint256) internal pure override { 17 | revert NotImplemented(); 18 | } 19 | } 20 | /* solhint-enable no-empty-blocks */ 21 | -------------------------------------------------------------------------------- /protocol/governance/contracts/storage/CouncilMembers.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import {SetUtil} from "@synthetixio/core-contracts/contracts/utils/SetUtil.sol"; 5 | 6 | library CouncilMembers { 7 | bytes32 private constant _STORAGE_SLOT = 8 | keccak256(abi.encode("io.synthetix.governance.CouncilMembers")); 9 | 10 | struct Data { 11 | // The address of the council NFT 12 | address councilToken; 13 | // Council member addresses 14 | SetUtil.AddressSet councilMembers; 15 | } 16 | 17 | function load() internal pure returns (Data storage store) { 18 | bytes32 s = _STORAGE_SLOT; 19 | assembly { 20 | store.slot := s 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /protocol/governance/contracts/storage/CrossChainDebtShare.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import "@synthetixio/core-contracts/contracts/utils/SetUtil.sol"; 5 | import "../interfaces/IDebtShare.sol"; 6 | 7 | library CrossChainDebtShare { 8 | struct Data { 9 | // Synthetix v2 cross chain debt share merkle root 10 | bytes32 merkleRoot; 11 | // Cross chain debt share merkle root snapshot blocknumber 12 | uint256 merkleRootBlockNumber; 13 | // Cross chain debt shares declared on this chain 14 | mapping(address => uint256) debtShares; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /protocol/governance/contracts/storage/SnapshotVotePowerEpoch.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | library SnapshotVotePowerEpoch { 5 | struct Data { 6 | uint128 snapshotId; 7 | mapping(address => uint256) recordedVotingPower; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /protocol/governance/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import commonConfig from '@synthetixio/common-config/hardhat.config'; 2 | import 'solidity-docgen'; 3 | import { templates } from '@synthetixio/docgen'; 4 | 5 | import './tasks/dev'; 6 | 7 | const config = { 8 | ...commonConfig, 9 | solidity: { 10 | version: '0.8.17', 11 | settings: { 12 | optimizer: { 13 | enabled: true, 14 | runs: 200, 15 | }, 16 | }, 17 | }, 18 | docgen: { 19 | exclude: [ 20 | './interfaces/external', 21 | './generated', 22 | './modules', 23 | './mocks', 24 | './storage', 25 | './submodules', 26 | './Proxy.sol', 27 | ], 28 | templates, 29 | }, 30 | warnings: { 31 | 'contracts/generated/**/*': { 32 | default: 'off', 33 | }, 34 | }, 35 | }; 36 | 37 | export default config; 38 | -------------------------------------------------------------------------------- /protocol/governance/test/constants.ts: -------------------------------------------------------------------------------- 1 | export enum ElectionPeriod { 2 | Administration = 0, 3 | Nomination = 1, 4 | Vote = 2, 5 | Evaluation = 3, 6 | } 7 | -------------------------------------------------------------------------------- /protocol/governance/test/helpers/object.ts: -------------------------------------------------------------------------------- 1 | type Obj = { [k: string]: unknown }; 2 | 3 | type Entry = { 4 | [K in keyof T]: [K, T[K]]; 5 | }[keyof T]; 6 | 7 | export function typedValues(obj: T) { 8 | return Object.values(obj as Obj) as T[keyof T][]; 9 | } 10 | 11 | export function typedEntries(obj: T) { 12 | return Object.entries(obj as Obj) as Entry[]; 13 | } 14 | -------------------------------------------------------------------------------- /protocol/governance/tomls/proxy-base.toml: -------------------------------------------------------------------------------- 1 | [setting.salt] 2 | defaultValue = "governance" 3 | 4 | [setting.bundleSalt] 5 | defaultValue = "" 6 | 7 | [setting.owner] 8 | 9 | [contract.InitialModuleBundle] 10 | artifact = "contracts/modules/core/InitialModuleBundle.sol:InitialModuleBundle" 11 | salt = "<%= settings.bundleSalt !== 'main' ? settings.bundleSalt : settings.salt %>" 12 | create2 = true 13 | ifExists = "continue" 14 | 15 | [contract.InitialProxy] 16 | artifact = "contracts/Proxy.sol:Proxy" 17 | args = ["<%= contracts.InitialModuleBundle.address %>", "<%= settings.owner %>"] 18 | salt = "<%= settings.salt %>" 19 | abiOf = ["InitialModuleBundle"] 20 | create2 = true 21 | 22 | [pull.trusted_multicall_forwarder] 23 | source = "trusted-multicall-forwarder@with-synthetix" 24 | -------------------------------------------------------------------------------- /protocol/oracle-manager/.gitignore: -------------------------------------------------------------------------------- 1 | cannon 2 | contracts/generated 3 | contracts/modules/test 4 | contracts/Router.sol 5 | deployments/hardhat 6 | deployments/local 7 | typechain-types 8 | -------------------------------------------------------------------------------- /protocol/oracle-manager/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require('@synthetixio/common-config/.solcover.js'), 3 | skipFiles: ['mocks', 'Router.sol'], 4 | }; 5 | -------------------------------------------------------------------------------- /protocol/oracle-manager/cannonfile.test.toml: -------------------------------------------------------------------------------- 1 | version = "<%= package.version %>-testable" 2 | include = ["cannonfile.toml"] 3 | -------------------------------------------------------------------------------- /protocol/oracle-manager/contracts/Dependencies.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/main/contracts/mocks/AggregatorV3Mock.sol"; 5 | -------------------------------------------------------------------------------- /protocol/oracle-manager/contracts/Proxy.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {UUPSProxyWithOwner} from "@synthetixio/core-contracts/contracts/proxy/UUPSProxyWithOwner.sol"; 5 | import {OwnableStorage} from "@synthetixio/core-contracts/contracts/ownership/OwnableStorage.sol"; 6 | 7 | /** 8 | * Synthetix Oracle Manager Proxy Contract 9 | * 10 | * Visit https://usecannon.com/packages/oracle-manager to interact with this protocol 11 | */ 12 | contract Proxy is UUPSProxyWithOwner { 13 | // solhint-disable-next-line no-empty-blocks 14 | constructor( 15 | address firstImplementation, 16 | address initialOwner 17 | ) UUPSProxyWithOwner(firstImplementation, initialOwner) {} 18 | } 19 | -------------------------------------------------------------------------------- /protocol/oracle-manager/contracts/interfaces/external/IExternalNode.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/core-contracts/contracts/interfaces/IERC165.sol"; 5 | 6 | import "../../storage/NodeOutput.sol"; 7 | import "../../storage/NodeDefinition.sol"; 8 | 9 | /// @title Interface for an external node 10 | interface IExternalNode is IERC165 { 11 | function process( 12 | NodeOutput.Data[] memory parentNodeOutputs, 13 | bytes memory parameters, 14 | bytes32[] memory runtimeKeys, 15 | bytes32[] memory runtimeValues 16 | ) external view returns (NodeOutput.Data memory); 17 | 18 | function isValid(NodeDefinition.Data memory nodeDefinition) external returns (bool); 19 | } 20 | -------------------------------------------------------------------------------- /protocol/oracle-manager/contracts/interfaces/external/IUniswapV3Pool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | interface IUniswapV3Pool { 5 | function observe( 6 | uint32[] calldata secondsAgos 7 | ) 8 | external 9 | view 10 | returns ( 11 | int56[] memory tickCumulatives, 12 | uint160[] memory secondsPerLiquidityCumulativeX128s 13 | ); 14 | 15 | function token0() external view returns (address); 16 | 17 | function token1() external view returns (address); 18 | } 19 | -------------------------------------------------------------------------------- /protocol/oracle-manager/contracts/mocks/ERC20Mock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {ERC20Mock} from "@synthetixio/core-contracts/contracts/mocks/token/ERC20Mock.sol"; 5 | -------------------------------------------------------------------------------- /protocol/oracle-manager/contracts/modules/CoreModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {CoreModule as BaseCoreModule} from "@synthetixio/core-modules/contracts/modules/CoreModule.sol"; 5 | 6 | // solhint-disable-next-line no-empty-blocks 7 | contract CoreModule is BaseCoreModule { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /protocol/oracle-manager/contracts/storage/NodeOutput.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | library NodeOutput { 5 | struct Data { 6 | /** 7 | * @dev Price returned from the oracle node, expressed with 18 decimals of precision 8 | */ 9 | int256 price; 10 | /** 11 | * @dev Timestamp associated with the price 12 | */ 13 | uint256 timestamp; 14 | // solhint-disable-next-line private-vars-leading-underscore 15 | uint256 __slotAvailableForFutureUse1; 16 | // solhint-disable-next-line private-vars-leading-underscore 17 | uint256 __slotAvailableForFutureUse2; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /protocol/oracle-manager/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import commonConfig from '@synthetixio/common-config/hardhat.config'; 2 | 3 | import 'solidity-docgen'; 4 | import { templates } from '@synthetixio/docgen'; 5 | 6 | const config = { 7 | ...commonConfig, 8 | docgen: { 9 | exclude: [ 10 | './interfaces/external', 11 | './generated', 12 | './modules', 13 | './mixins', 14 | './mocks', 15 | './utils', 16 | './storage', 17 | './Proxy.sol', 18 | './Router.sol', 19 | ], 20 | templates, 21 | }, 22 | }; 23 | 24 | export default config; 25 | -------------------------------------------------------------------------------- /protocol/oracle-manager/test/common/index.ts: -------------------------------------------------------------------------------- 1 | export * from './oracleNode'; 2 | -------------------------------------------------------------------------------- /protocol/oracle-manager/test/integration/mixins/Node.operations.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | RECENT: 0, 3 | MIN: 1, 4 | MAX: 2, 5 | MEAN: 3, 6 | MEDIAN: 4, 7 | MUL: 5, 8 | DIV: 6, 9 | MULDECIMAL: 7, 10 | DIVDECIMAL: 8, 11 | }; 12 | -------------------------------------------------------------------------------- /protocol/oracle-manager/test/integration/mixins/Node.types.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | NONE: 0, 3 | REDUCER: 1, 4 | EXTERNAL: 2, 5 | CHAINLINK: 3, 6 | UNISWAP: 4, 7 | PYTH: 5, 8 | PRICE_DEVIATION_CIRCUIT_BREAKER: 6, 9 | STALENESS_CIRCUIT_BREAKER: 7, 10 | CONSTANT: 8, 11 | PYTH_OFFCHAIN_LOOKUP: 9, 12 | }; 13 | -------------------------------------------------------------------------------- /protocol/synthetix/.gitignore: -------------------------------------------------------------------------------- 1 | deployments/local 2 | deployments/hardhat 3 | 4 | cannon 5 | typechain-types 6 | 7 | # generated test modules 8 | contracts/modules/test 9 | contracts/generated 10 | 11 | # generated routers 12 | contracts/routers 13 | 14 | # generated contract typings 15 | test/generated/typechain 16 | -------------------------------------------------------------------------------- /protocol/synthetix/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require('@synthetixio/common-config/.solcover.js'), 3 | skipFiles: ['mocks', 'routers', 'generated'], 4 | }; 5 | -------------------------------------------------------------------------------- /protocol/synthetix/cannonfile.toml: -------------------------------------------------------------------------------- 1 | name = "synthetix" 2 | version = "<%= package.version %>" 3 | description = "Core synthetix system" 4 | 5 | include = ["./cannonfile.common.toml"] 6 | 7 | [import.oracle_manager] 8 | source = "<%= settings.oracle_manager_package %>" 9 | -------------------------------------------------------------------------------- /protocol/synthetix/contracts/Proxy.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {UUPSProxyWithOwner} from "@synthetixio/core-contracts/contracts/proxy/UUPSProxyWithOwner.sol"; 5 | 6 | /** 7 | * Synthetix V3 Core Proxy Contract 8 | * 9 | * Visit https://usecannon.com/packages/synthetix to interact with this protocol 10 | */ 11 | contract Proxy is UUPSProxyWithOwner { 12 | // solhint-disable-next-line no-empty-blocks 13 | constructor( 14 | address firstImplementation, 15 | address initialOwner 16 | ) UUPSProxyWithOwner(firstImplementation, initialOwner) {} 17 | } 18 | -------------------------------------------------------------------------------- /protocol/synthetix/contracts/interfaces/IAccountTokenModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/core-modules/contracts/interfaces/INftModule.sol"; 5 | 6 | /** 7 | * @title Module with custom NFT logic for the account token. 8 | */ 9 | // solhint-disable-next-line no-empty-blocks 10 | interface IAccountTokenModule is INftModule {} 11 | -------------------------------------------------------------------------------- /protocol/synthetix/contracts/interfaces/external/IAny2EVMMessageReceiver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.4; 3 | 4 | import "../../utils/CcipClient.sol"; 5 | 6 | /// @notice Application contracts that intend to receive messages from 7 | /// the router should implement this interface. 8 | interface IAny2EVMMessageReceiver { 9 | /// @notice Router calls this to deliver a message. 10 | /// If this reverts, any token transfers also revert. The message 11 | /// will move to a FAILED state and become available for manual execution 12 | /// as a retry. Fees already paid are NOT currently refunded (may change). 13 | /// @param message CCIP Message 14 | /// @dev Note ensure you check the msg.sender is the router 15 | function ccipReceive(CcipClient.Any2EVMMessage calldata message) external; 16 | } 17 | -------------------------------------------------------------------------------- /protocol/synthetix/contracts/interfaces/external/IMarket.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/core-contracts/contracts/interfaces/IERC165.sol"; 5 | 6 | /// @title Interface for markets integrated with Synthetix 7 | interface IMarket is IERC165 { 8 | /// @notice returns a human-readable name for a given market 9 | function name(uint128 marketId) external view returns (string memory); 10 | 11 | /// @notice returns amount of USD that the market would try to mint if everything was withdrawn 12 | function reportedDebt(uint128 marketId) external view returns (uint256); 13 | 14 | /// @notice prevents reduction of available credit capacity by specifying this amount, for which withdrawals will be disallowed 15 | function minimumCredit(uint128 marketId) external view returns (uint256); 16 | } 17 | -------------------------------------------------------------------------------- /protocol/synthetix/contracts/interfaces/external/IOracleManager.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/oracle-manager/contracts/interfaces/INodeModule.sol"; 5 | 6 | /// @title Effective interface for the oracle manager 7 | // solhint-disable-next-line no-empty-blocks 8 | interface IOracleManager is INodeModule {} 9 | -------------------------------------------------------------------------------- /protocol/synthetix/contracts/mocks/CcipRouterMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.4; 3 | 4 | import "../interfaces/external/ICcipRouterClient.sol"; 5 | 6 | contract CcipRouterMock { 7 | // solhint-disable no-empty-blocks 8 | function ccipSend( 9 | uint64 destinationChainId, 10 | CcipClient.EVM2AnyMessage calldata message 11 | ) external payable virtual returns (bytes32 messageId) {} 12 | 13 | function getFee( 14 | uint64 destinationChainId, 15 | CcipClient.EVM2AnyMessage memory message 16 | ) external view virtual returns (uint256 fee) {} 17 | // solhint-enable no-empty-blocks 18 | } 19 | -------------------------------------------------------------------------------- /protocol/synthetix/contracts/mocks/CollateralMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/core-contracts/contracts/token/ERC20.sol"; 5 | 6 | contract CollateralMock is ERC20 { 7 | function initialize( 8 | string memory tokenName, 9 | string memory tokenSymbol, 10 | uint8 tokenDecimals 11 | ) public { 12 | _initialize(tokenName, tokenSymbol, tokenDecimals); 13 | } 14 | 15 | function burn(uint256 amount) external { 16 | _burn(ERC2771Context._msgSender(), amount); 17 | } 18 | 19 | function mint(address recipient, uint256 amount) external { 20 | _mint(recipient, amount); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /protocol/synthetix/contracts/modules/InitialModuleBundle.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "./common/OwnerModule.sol"; 5 | import "./common/UpgradeModule.sol"; 6 | 7 | // The below contract is only used during initialization as a kernel for the first release which the system can be upgraded onto. 8 | // Subsequent upgrades will not need this module bundle 9 | // In the future on live networks, we may want to find some way to hardcode the owner address here to prevent grieving 10 | 11 | // solhint-disable-next-line no-empty-blocks 12 | contract InitialModuleBundle is OwnerModule, UpgradeModule { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /protocol/synthetix/contracts/modules/associated-systems/AssociatedSystemsModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {AssociatedSystemsModule as BaseAssociatedSystemsModule} from "@synthetixio/core-modules/contracts/modules/AssociatedSystemsModule.sol"; 5 | 6 | /** 7 | * @title Module for connecting to other systems. 8 | * See core-modules/../AssociatedSystemsModule 9 | */ 10 | // solhint-disable-next-line no-empty-blocks 11 | contract AssociatedSystemsModule is BaseAssociatedSystemsModule {} 12 | -------------------------------------------------------------------------------- /protocol/synthetix/contracts/modules/common/OwnerModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {OwnerModule as BaseOwnerModule} from "@synthetixio/core-modules/contracts/modules/OwnerModule.sol"; 5 | 6 | /** 7 | * @title Module for owner based access control. 8 | * See core-modules/../OwnerModule 9 | */ 10 | // solhint-disable-next-line no-empty-blocks 11 | contract OwnerModule is BaseOwnerModule { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /protocol/synthetix/contracts/modules/common/UpgradeModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {UpgradeModule as BaseUpgradeModule} from "@synthetixio/core-modules/contracts/modules/UpgradeModule.sol"; 5 | 6 | /** 7 | * @title Module UUPS type upgradeability. 8 | * See core-modules/../UpgradeModule 9 | */ 10 | // solhint-disable-next-line no-empty-blocks 11 | contract UpgradeModule is BaseUpgradeModule { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /protocol/synthetix/contracts/modules/core/FeatureFlagModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {FeatureFlagModule as BaseFeatureFlagModule} from "@synthetixio/core-modules/contracts/modules/FeatureFlagModule.sol"; 5 | 6 | /** 7 | * @title Module that allows disabling certain system features. 8 | * 9 | * Users will not be able to interact with certain functions associated to disabled features. 10 | */ 11 | // solhint-disable-next-line no-empty-blocks 12 | contract FeatureFlagModule is BaseFeatureFlagModule {} 13 | -------------------------------------------------------------------------------- /protocol/synthetix/contracts/storage/CollateralLock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title Represents a given amount of collateral locked until a given date. 6 | */ 7 | library CollateralLock { 8 | struct Data { 9 | /** 10 | * @dev The amount of collateral that has been locked. 11 | */ 12 | uint128 amountD18; 13 | /** 14 | * @dev The date when the locked amount becomes unlocked. 15 | */ 16 | uint64 lockExpirationTime; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /protocol/synthetix/contracts/storage/DistributionActor.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title Stores information for specific actors in a Distribution. 6 | */ 7 | library DistributionActor { 8 | struct Data { 9 | /** 10 | * @dev The actor's current number of shares in the associated distribution. 11 | */ 12 | uint128 sharesD18; 13 | /** 14 | * @dev The value per share that the associated distribution had at the time that the actor's number of shares was last modified. 15 | * 16 | * Note: This is also a high precision decimal. See Distribution.valuePerShare. 17 | */ 18 | int128 lastValuePerShareD27; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /protocol/synthetix/contracts/storage/MarketPoolInfo.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title Stores information regarding a pool's relationship to a market, such that it can be added or removed from a distribution 6 | */ 7 | library MarketPoolInfo { 8 | struct Data { 9 | /** 10 | * @dev The credit capacity that this pool is providing to the relevant market. Needed to re-add the pool to the distribution when going back in range. 11 | */ 12 | uint128 creditCapacityAmountD18; 13 | /** 14 | * @dev The amount of debt the pool has which hasn't been passed down the debt distribution chain yet. 15 | */ 16 | uint128 pendingDebtD18; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /protocol/synthetix/contracts/storage/OracleManager.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title Represents Oracle Manager 6 | */ 7 | library OracleManager { 8 | bytes32 private constant _SLOT_ORACLE_MANAGER = 9 | keccak256(abi.encode("io.synthetix.synthetix.OracleManager")); 10 | 11 | struct Data { 12 | /** 13 | * @dev The oracle manager address. 14 | */ 15 | address oracleManagerAddress; 16 | } 17 | 18 | /** 19 | * @dev Loads the singleton storage info about the oracle manager. 20 | */ 21 | function load() internal pure returns (Data storage oracleManager) { 22 | bytes32 s = _SLOT_ORACLE_MANAGER; 23 | assembly { 24 | oracleManager.slot := s 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /protocol/synthetix/contracts/storage/PoolCollateralConfiguration.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | library PoolCollateralConfiguration { 5 | bytes32 private constant _SLOT = 6 | keccak256(abi.encode("io.synthetix.synthetix.PoolCollateralConfiguration")); 7 | 8 | struct Data { 9 | uint256 collateralLimitD18; 10 | uint256 issuanceRatioD18; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /protocol/synthetix/contracts/storage/RewardDistributionClaimStatus.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title Tracks information per actor within a RewardDistribution. 6 | */ 7 | library RewardDistributionClaimStatus { 8 | struct Data { 9 | /** 10 | * @dev The last known reward per share for this actor. 11 | */ 12 | uint128 lastRewardPerShareD18; 13 | /** 14 | * @dev The amount of rewards pending to be claimed by this actor. 15 | */ 16 | uint128 pendingSendD18; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /protocol/synthetix/subgraph/.gitignore: -------------------------------------------------------------------------------- 1 | .bin/ 2 | tests/.bin/ 3 | tests/.latest.json 4 | subgraph.yaml 5 | **/deployments/ 6 | build/ 7 | -------------------------------------------------------------------------------- /protocol/synthetix/subgraph/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | export CANNON_IPFS_URL="https://ipfs.synthetix.io" 5 | 6 | build() { 7 | namespace=$1 8 | 9 | echo 10 | echo 11 | echo 12 | echo '>' graph build "subgraph.$namespace.yaml" --output-dir "./build/$namespace" 13 | yarn graph build "subgraph.$namespace.yaml" --output-dir "./build/$namespace" 14 | yarn prettier --write "subgraph.$namespace.yaml" 15 | } 16 | 17 | build base-sepolia-andromeda 18 | build base-mainnet-andromeda 19 | build mainnet 20 | build sepolia 21 | build optimism-mainnet 22 | build arbitrum-mainnet 23 | build arbitrum-sepolia 24 | -------------------------------------------------------------------------------- /protocol/synthetix/subgraph/mainnet/handleAccountCreated.ts: -------------------------------------------------------------------------------- 1 | import { AccountCreated } from './generated/CoreProxy/CoreProxy'; 2 | import { Account } from './generated/schema'; 3 | 4 | export function handleAccountCreated(event: AccountCreated): void { 5 | const account = new Account(event.params.accountId.toString()); 6 | account.owner = event.params.owner; 7 | account.created_at = event.block.timestamp; 8 | account.created_at_block = event.block.number; 9 | account.updated_at = event.block.timestamp; 10 | account.updated_at_block = event.block.number; 11 | account.permissions = []; 12 | account.save(); 13 | } 14 | -------------------------------------------------------------------------------- /protocol/synthetix/subgraph/mainnet/handleCollateralWithdrawn.ts: -------------------------------------------------------------------------------- 1 | import { Withdrawn } from './generated/CoreProxy/CoreProxy'; 2 | import { CollateralType } from './generated/schema'; 3 | 4 | export function handleCollateralWithdrawn(event: Withdrawn): void { 5 | let collateralType = CollateralType.load(event.params.collateralType.toHex()); 6 | if (collateralType) { 7 | collateralType.updated_at = event.block.timestamp; 8 | collateralType.updated_at_block = event.block.number; 9 | if (collateralType.total_amount_deposited !== null) { 10 | // @dev we could also account for every account how much they deposited and withdrawn 11 | collateralType.total_amount_deposited = collateralType.total_amount_deposited!.minus( 12 | event.params.tokenAmount.toBigDecimal() 13 | ); 14 | } 15 | collateralType.save(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /protocol/synthetix/subgraph/mainnet/handlePoolCreated.ts: -------------------------------------------------------------------------------- 1 | import { PoolCreated } from './generated/CoreProxy/CoreProxy'; 2 | import { Pool } from './generated/schema'; 3 | 4 | export function handlePoolCreated(event: PoolCreated): void { 5 | const newPool = new Pool(event.params.poolId.toString()); 6 | newPool.owner = event.params.owner; 7 | newPool.created_at = event.block.timestamp; 8 | newPool.created_at_block = event.block.number; 9 | newPool.updated_at = event.block.timestamp; 10 | newPool.updated_at_block = event.block.number; 11 | newPool.save(); 12 | } 13 | -------------------------------------------------------------------------------- /protocol/synthetix/subgraph/mainnet/handlePoolNameUpdated.ts: -------------------------------------------------------------------------------- 1 | import { PoolNameUpdated } from './generated/CoreProxy/CoreProxy'; 2 | import { Pool } from './generated/schema'; 3 | 4 | export function handlePoolNameUpdated(event: PoolNameUpdated): void { 5 | const pool = Pool.load(event.params.poolId.toString()); 6 | if (pool !== null) { 7 | pool.name = event.params.name.toString(); 8 | pool.updated_at_block = event.block.number; 9 | pool.updated_at = event.block.timestamp; 10 | pool.save(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /protocol/synthetix/subgraph/mainnet/handlePoolNominationRenounced.ts: -------------------------------------------------------------------------------- 1 | import { PoolNominationRenounced } from './generated/CoreProxy/CoreProxy'; 2 | import { Pool } from './generated/schema'; 3 | import { Bytes } from '@graphprotocol/graph-ts'; 4 | 5 | export function handlePoolNominationRenounced(event: PoolNominationRenounced): void { 6 | const pool = Pool.load(event.params.poolId.toString()); 7 | if (pool !== null) { 8 | pool.nominated_owner = Bytes.empty(); 9 | pool.updated_at = event.block.timestamp; 10 | pool.updated_at_block = event.block.number; 11 | pool.save(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /protocol/synthetix/subgraph/mainnet/handlePoolNominationRevoked.ts: -------------------------------------------------------------------------------- 1 | import { PoolNominationRevoked } from './generated/CoreProxy/CoreProxy'; 2 | import { Pool } from './generated/schema'; 3 | import { Bytes } from '@graphprotocol/graph-ts'; 4 | 5 | export function handlePoolNominationRevoked(event: PoolNominationRevoked): void { 6 | const pool = Pool.load(event.params.poolId.toString()); 7 | if (pool !== null) { 8 | pool.nominated_owner = Bytes.empty(); 9 | pool.updated_at = event.block.timestamp; 10 | pool.updated_at_block = event.block.number; 11 | pool.save(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /protocol/synthetix/subgraph/mainnet/handlePoolOwnerNominated.ts: -------------------------------------------------------------------------------- 1 | import { PoolOwnerNominated } from './generated/CoreProxy/CoreProxy'; 2 | import { Pool } from './generated/schema'; 3 | 4 | export function handlePoolOwnerNominated(event: PoolOwnerNominated): void { 5 | const pool = Pool.load(event.params.poolId.toString()); 6 | if (pool !== null) { 7 | pool.nominated_owner = event.params.nominatedOwner; 8 | pool.updated_at = event.block.timestamp; 9 | pool.updated_at_block = event.block.number; 10 | pool.save(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /protocol/synthetix/subgraph/mainnet/handlePoolOwnershipAccepted.ts: -------------------------------------------------------------------------------- 1 | import { PoolOwnershipAccepted } from './generated/CoreProxy/CoreProxy'; 2 | import { Pool } from './generated/schema'; 3 | import { Bytes } from '@graphprotocol/graph-ts'; 4 | 5 | export function handlePoolOwnershipAccepted(event: PoolOwnershipAccepted): void { 6 | const pool = Pool.load(event.params.poolId.toString()); 7 | if (pool !== null) { 8 | pool.updated_at_block = event.block.number; 9 | pool.updated_at = event.block.timestamp; 10 | pool.owner = event.params.owner; 11 | pool.nominated_owner = Bytes.empty(); 12 | pool.save(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /protocol/synthetix/subgraph/mainnet/handleRewardsDistributorRemoved.ts: -------------------------------------------------------------------------------- 1 | import { RewardsDistributorRemoved } from './generated/CoreProxy/CoreProxy'; 2 | import { RewardsDistributor } from './generated/schema'; 3 | 4 | export function handleRewardsDistributorRemoved(event: RewardsDistributorRemoved): void { 5 | const distributor = RewardsDistributor.load(event.params.distributor.toHex()); 6 | 7 | if (distributor !== null) { 8 | distributor.updated_at = event.block.timestamp; 9 | distributor.updated_at_block = event.block.number; 10 | distributor.isActive = false; 11 | distributor.save(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /protocol/synthetix/subgraph/matchstick.yaml: -------------------------------------------------------------------------------- 1 | testFolder: tests/ 2 | libsFolder: ../../../node_modules/ 3 | manifestPath: ./subgraph.mainnet.yaml 4 | -------------------------------------------------------------------------------- /protocol/synthetix/subgraph/tests/constants.ts: -------------------------------------------------------------------------------- 1 | export const address = '0xd8da6bf26964af9d7eed9e03e53415d37aa96045'; 2 | export const address2 = '0x42f9134e9d3bf7eee1f8a5ac2a4328b059e7468c'; 3 | export const defaultGraphContractAddress = '0xa16081f360e3847006db660bae1c6d1b2e17ec2a'; 4 | -------------------------------------------------------------------------------- /protocol/synthetix/subgraph/tests/event-factories/utils.ts: -------------------------------------------------------------------------------- 1 | export function createBlock(timestamp: i64, blockNumber: i64): Map { 2 | const newBlock = new Map(); 3 | newBlock.set('timestamp', timestamp); 4 | newBlock.set('blockNumber', blockNumber); 5 | return newBlock; 6 | } 7 | -------------------------------------------------------------------------------- /protocol/synthetix/subgraph/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@graphprotocol/graph-ts/types/tsconfig.base.json", 3 | "include": [ 4 | "mainnet", 5 | "sepolia", 6 | "optimism-mainnet", 7 | "optimism-sepolia", 8 | "base", 9 | "base-sepolia", 10 | "arbitrum", 11 | "arbitrum-sepolia" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /protocol/synthetix/test/common/index.ts: -------------------------------------------------------------------------------- 1 | export * from './stakers'; 2 | export * from './stakedPool'; 3 | -------------------------------------------------------------------------------- /protocol/synthetix/test/integration/mixins/AccountRBACMixin.permissions.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'ethers'; 2 | 3 | export default { 4 | ADMIN: ethers.utils.formatBytes32String('ADMIN'), 5 | WITHDRAW: ethers.utils.formatBytes32String('WITHDRAW'), 6 | MINT: ethers.utils.formatBytes32String('MINT'), 7 | DELEGATE: ethers.utils.formatBytes32String('DELEGATE'), 8 | REWARDS: ethers.utils.formatBytes32String('REWARDS'), 9 | BURN: ethers.utils.formatBytes32String('BURN'), 10 | }; 11 | -------------------------------------------------------------------------------- /tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": [ 4 | "./utils/**/*.ts", 5 | "./utils/**/*.js", 6 | "./protocol/**/*.ts", 7 | "./protocol/**/*.js", 8 | "./markets/**/*.ts", 9 | "./markets/**/*.js", 10 | "./auxiliary/**/*.js", 11 | "./auxiliary/**/*.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "noEmit": true, 4 | "target": "ESNext", 5 | "module": "Node16", 6 | "moduleResolution": "node16", 7 | "lib": ["esnext"], 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "resolveJsonModule": true, 12 | "skipLibCheck": true, 13 | "declaration": true, 14 | "declarationMap": true, 15 | "sourceMap": true 16 | }, 17 | "exclude": ["**/subgraph/**/*"] 18 | } 19 | -------------------------------------------------------------------------------- /utils/common-config/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // Reduce instrumentation footprint - volume of solidity code 3 | // passed to compiler causes it to crash 4 | // Line and branch coverage will still be reported. 5 | measureStatementCoverage: false, 6 | measureFunctionCoverage: false, 7 | }; 8 | -------------------------------------------------------------------------------- /utils/core-contracts/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require('@synthetixio/common-config/.solcover.js'), 3 | skipFiles: ['mocks'], 4 | }; 5 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/errors/AccessError.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title Library for access related errors. 6 | */ 7 | library AccessError { 8 | /** 9 | * @dev Thrown when an address tries to perform an unauthorized action. 10 | * @param addr The address that attempts the action. 11 | */ 12 | error Unauthorized(address addr); 13 | } 14 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/errors/AddressError.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title Library for address related errors. 6 | */ 7 | library AddressError { 8 | /** 9 | * @dev Thrown when a zero address was passed as a function parameter (0x0000000000000000000000000000000000000000). 10 | */ 11 | error ZeroAddress(); 12 | 13 | /** 14 | * @dev Thrown when an address representing a contract is expected, but no code is found at the address. 15 | * @param contr The address that was expected to be a contract. 16 | */ 17 | error NotAContract(address contr); 18 | } 19 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/errors/ArrayError.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title Library for array related errors. 6 | */ 7 | library ArrayError { 8 | /** 9 | * @dev Thrown when an unexpected empty array is detected. 10 | */ 11 | error EmptyArray(); 12 | 13 | /** 14 | * @dev Thrown when attempting to access an array beyond its current number of items. 15 | */ 16 | error OutOfBounds(); 17 | } 18 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/errors/ChangeError.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title Library for change related errors. 6 | */ 7 | library ChangeError { 8 | /** 9 | * @dev Thrown when a change is expected but none is detected. 10 | */ 11 | error NoChange(); 12 | } 13 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/errors/InitError.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title Library for initialization related errors. 6 | */ 7 | library InitError { 8 | /** 9 | * @dev Thrown when attempting to initialize a contract that is already initialized. 10 | */ 11 | error AlreadyInitialized(); 12 | 13 | /** 14 | * @dev Thrown when attempting to interact with a contract that has not been initialized yet. 15 | */ 16 | error NotInitialized(); 17 | } 18 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/errors/ParameterError.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title Library for errors related with expected function parameters. 6 | */ 7 | library ParameterError { 8 | /** 9 | * @dev Thrown when an invalid parameter is used in a function. 10 | * @param parameter The name of the parameter. 11 | * @param reason The reason why the received parameter is invalid. 12 | */ 13 | error InvalidParameter(string parameter, string reason); 14 | } 15 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/interfaces/IERC165.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title ERC165 interface for determining if a contract supports a given interface. 6 | */ 7 | interface IERC165 { 8 | /** 9 | * @notice Determines if the contract in question supports the specified interface. 10 | * @param interfaceID XOR of all selectors in the contract. 11 | * @return True if the contract supports the specified interface. 12 | */ 13 | function supportsInterface(bytes4 interfaceID) external view returns (bool); 14 | } 15 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/mocks/proxy/ImplementationDestroyer.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | // solhint-disable-next-line no-empty-blocks 5 | contract ImplementationDestroyer { 6 | function upgradeTo(address) public { 7 | selfdestruct(payable(0)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/mocks/proxy/ImplementationMockA.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "./UUPSImplementationMock.sol"; 5 | 6 | contract ImplementationMockA is UUPSImplementationMock { 7 | uint256 private _a; 8 | 9 | function setA(uint256 newA) external { 10 | _a = newA; 11 | } 12 | 13 | function getA() external view returns (uint256) { 14 | return _a; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/mocks/proxy/SterileImplementation.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | // solhint-disable-next-line no-empty-blocks 5 | contract SterileImplementation {} 6 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/mocks/proxy/UUPSImplementationMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "../../proxy/UUPSImplementation.sol"; 5 | 6 | contract UUPSImplementationMock is UUPSImplementation { 7 | function upgradeTo(address newImplementation) public override { 8 | _upgradeTo(newImplementation); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/mocks/token/ERC20PermitMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "../../token/ERC20Permit.sol"; 5 | 6 | contract ERC20PermitMock is ERC20Permit { 7 | function initialize( 8 | string memory tokenName, 9 | string memory tokenSymbol, 10 | uint8 tokenDecimals 11 | ) public { 12 | _initialize(tokenName, tokenSymbol, tokenDecimals); 13 | } 14 | 15 | function mint(uint256 amount) external { 16 | _mint(ERC2771Context._msgSender(), amount); 17 | } 18 | 19 | function burn(uint256 amount) external { 20 | _burn(ERC2771Context._msgSender(), amount); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/mocks/token/ERC721EnumerableMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "../../token/ERC721Enumerable.sol"; 5 | 6 | contract ERC721EnumerableMock is ERC721Enumerable { 7 | function initialize( 8 | string memory tokenName, 9 | string memory tokenSymbol, 10 | string memory baseURL 11 | ) public { 12 | _initialize(tokenName, tokenSymbol, baseURL); 13 | } 14 | 15 | function mintTo(address to, uint256 tokenId) external { 16 | _mint(to, tokenId); 17 | } 18 | 19 | function burn(uint256 tokenId) external { 20 | _burn(tokenId); 21 | } 22 | 23 | function transfer(address from, address to, uint256 tokenId) external { 24 | _transfer(from, to, tokenId); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/mocks/token/ERC721FailedReceiverMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "../../interfaces/IERC721Receiver.sol"; 5 | 6 | contract ERC721FailedReceiverMock is IERC721Receiver { 7 | function onERC721Received( 8 | address, 9 | address, 10 | uint256, 11 | bytes memory 12 | ) public pure override returns (bytes4) { 13 | return 0x11223344; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/mocks/token/ERC721Mock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "../../token/ERC721.sol"; 5 | 6 | contract ERC721Mock is ERC721 { 7 | function initialize( 8 | string memory tokenName, 9 | string memory tokenSymbol, 10 | string memory baseURL 11 | ) public { 12 | _initialize(tokenName, tokenSymbol, baseURL); 13 | } 14 | 15 | function mint(uint256 tokenId) external { 16 | _mint(ERC2771Context._msgSender(), tokenId); 17 | } 18 | 19 | function mintTo(address to, uint256 tokenId) external { 20 | _mint(to, tokenId); 21 | } 22 | 23 | function burn(uint256 tokenId) external { 24 | _burn(tokenId); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/mocks/token/ERC721OwnedMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "../../token/ERC721Owned.sol"; 5 | 6 | contract ERC721OwnedMock is ERC721Owned { 7 | // solhint-disable-next-line no-empty-blocks 8 | constructor(address initialOwner) ERC721Owned(initialOwner) {} 9 | 10 | function initialize( 11 | string memory tokenName, 12 | string memory tokenSymbol, 13 | string memory baseURL 14 | ) public { 15 | _initialize(tokenName, tokenSymbol, baseURL); 16 | } 17 | 18 | function mint(uint256 tokenId) external { 19 | _mint(ERC2771Context._msgSender(), tokenId); 20 | } 21 | 22 | function mintTo(address to, uint256 tokenId) external { 23 | _mint(to, tokenId); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/mocks/token/ERC721ReceiverMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "../../interfaces/IERC721Receiver.sol"; 5 | import "../../interfaces/IERC721.sol"; 6 | 7 | contract ERC721ReceiverMock is IERC721Receiver { 8 | function onERC721Received( 9 | address, 10 | address, 11 | uint256, 12 | bytes memory 13 | ) public pure override returns (bytes4) { 14 | return this.onERC721Received.selector; 15 | } 16 | 17 | function transferToken(address nftAddress, address to, uint256 tokenId) public { 18 | IERC721(nftAddress).transferFrom(address(this), to, tokenId); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/mocks/token/ERC721RevertingReceiverMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "../../interfaces/IERC721Receiver.sol"; 5 | 6 | contract ERC721RevertingReceiverMock is IERC721Receiver { 7 | error SomeFancyError(); 8 | 9 | function onERC721Received( 10 | address, 11 | address, 12 | uint256, 13 | bytes memory 14 | ) public pure override returns (bytes4) { 15 | revert SomeFancyError(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/mocks/token/VaultMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "../../token/ERC20.sol"; 5 | import "../../interfaces/IERC20Permit.sol"; 6 | 7 | contract VaultMock { 8 | IERC20Permit public token; 9 | 10 | function initialize(address _token) public { 11 | token = IERC20Permit(_token); 12 | } 13 | 14 | function depositWithPermit( 15 | uint256 amount, 16 | uint256 deadline, 17 | uint8 v, 18 | bytes32 r, 19 | bytes32 s 20 | ) external { 21 | token.permit(ERC2771Context._msgSender(), address(this), amount, deadline, v, r, s); 22 | token.transferFrom(ERC2771Context._msgSender(), address(this), amount); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/mocks/utils/AddressUtilMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "../../utils/AddressUtil.sol"; 5 | 6 | contract AddressUtilMock { 7 | function isContract(address account) public view returns (bool) { 8 | return AddressUtil.isContract(account); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/mocks/utils/ERC165HelperMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "../../interfaces/IERC20.sol"; 5 | import "../../interfaces/IERC721.sol"; 6 | import "../../utils/ERC165Helper.sol"; 7 | 8 | contract ERC165HelperMock { 9 | function supportsInterface(address candidate, bytes4 interfaceId) external returns (bool) { 10 | return ERC165Helper.safeSupportsInterface(candidate, interfaceId); 11 | } 12 | 13 | function getERC20InterfaceId() external pure returns (bytes4) { 14 | return type(IERC20).interfaceId; 15 | } 16 | 17 | function getERC721InterfaceId() external pure returns (bytes4) { 18 | return type(IERC721).interfaceId; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/mocks/utils/MerkleProofMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "../../utils/MerkleProof.sol"; 5 | 6 | contract MerkleProofMock { 7 | function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) public pure returns (bool) { 8 | return MerkleProof.verify(proof, root, leaf); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/mocks/utils/RevertUtilMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "../../utils/RevertUtil.sol"; 5 | 6 | contract RevertUtilMock { 7 | function revertIfError(bytes memory reason) external pure { 8 | RevertUtil.revertIfError(reason); 9 | } 10 | 11 | function revertManyIfError(bytes[] memory reasons) external pure { 12 | RevertUtil.revertManyIfError(reasons); 13 | } 14 | 15 | function revertWithReason(bytes memory reason) external pure { 16 | RevertUtil.revertWithReason(reason); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/mocks/utils/StringUtilMock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "../../utils/StringUtil.sol"; 5 | 6 | contract StringUtilMock { 7 | function uintToString(uint256 value) public pure returns (string memory) { 8 | return StringUtil.uintToString(value); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/proxy/ProxyStorage.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | contract ProxyStorage { 5 | bytes32 private constant _SLOT_PROXY_STORAGE = 6 | keccak256(abi.encode("io.synthetix.core-contracts.Proxy")); 7 | 8 | struct ProxyStore { 9 | address implementation; 10 | bool simulatingUpgrade; 11 | } 12 | 13 | function _proxyStore() internal pure returns (ProxyStore storage store) { 14 | bytes32 s = _SLOT_PROXY_STORAGE; 15 | assembly { 16 | store.slot := s 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/proxy/UUPSProxyWithOwner.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {UUPSProxy} from "./UUPSProxy.sol"; 5 | import {OwnableStorage} from "../ownership/OwnableStorage.sol"; 6 | 7 | contract UUPSProxyWithOwner is UUPSProxy { 8 | // solhint-disable-next-line no-empty-blocks 9 | constructor(address firstImplementation, address initialOwner) UUPSProxy(firstImplementation) { 10 | OwnableStorage.load().owner = initialOwner; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/token/ERC20PermitStorage.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | library ERC20PermitStorage { 5 | bytes32 private constant _SLOT_ERC20_PERMIT = 6 | keccak256(abi.encode("io.synthetix.core-contracts.ERC20Permit")); 7 | 8 | struct Data { 9 | uint256 initialChainId; 10 | bytes32 initialDomainSeprator; 11 | mapping(address => uint256) nonces; 12 | } 13 | 14 | function load() internal pure returns (Data storage store) { 15 | bytes32 s = _SLOT_ERC20_PERMIT; 16 | assembly { 17 | store.slot := s 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/token/ERC20Storage.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | library ERC20Storage { 5 | bytes32 private constant _SLOT_ERC20_STORAGE = 6 | keccak256(abi.encode("io.synthetix.core-contracts.ERC20")); 7 | 8 | struct Data { 9 | string name; 10 | string symbol; 11 | uint8 decimals; 12 | mapping(address => uint256) balanceOf; 13 | mapping(address => mapping(address => uint256)) allowance; 14 | uint256 totalSupply; 15 | } 16 | 17 | function load() internal pure returns (Data storage store) { 18 | bytes32 s = _SLOT_ERC20_STORAGE; 19 | assembly { 20 | store.slot := s 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/token/ERC721EnumerableStorage.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | library ERC721EnumerableStorage { 5 | bytes32 private constant _SLOT_ERC721_ENUMERABLE_STORAGE = 6 | keccak256(abi.encode("io.synthetix.core-contracts.ERC721Enumerable")); 7 | 8 | struct Data { 9 | mapping(uint256 => uint256) ownedTokensIndex; 10 | mapping(uint256 => uint256) allTokensIndex; 11 | mapping(address => mapping(uint256 => uint256)) ownedTokens; 12 | uint256[] allTokens; 13 | } 14 | 15 | function load() internal pure returns (Data storage store) { 16 | bytes32 s = _SLOT_ERC721_ENUMERABLE_STORAGE; 17 | assembly { 18 | store.slot := s 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/token/ERC721Storage.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | library ERC721Storage { 5 | bytes32 private constant _SLOT_ERC721_STORAGE = 6 | keccak256(abi.encode("io.synthetix.core-contracts.ERC721")); 7 | 8 | struct Data { 9 | string name; 10 | string symbol; 11 | string baseTokenURI; 12 | mapping(uint256 => address) ownerOf; 13 | mapping(address => uint256) balanceOf; 14 | mapping(uint256 => address) tokenApprovals; 15 | mapping(address => mapping(address => bool)) operatorApprovals; 16 | } 17 | 18 | function load() internal pure returns (Data storage store) { 19 | bytes32 s = _SLOT_ERC721_STORAGE; 20 | assembly { 21 | store.slot := s 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/utils/AddressUtil.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | library AddressUtil { 5 | function isContract(address account) internal view returns (bool) { 6 | uint256 size; 7 | 8 | assembly { 9 | size := extcodesize(account) 10 | } 11 | 12 | return size > 0; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/utils/ERC165Helper.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "../interfaces/IERC165.sol"; 5 | 6 | library ERC165Helper { 7 | function safeSupportsInterface( 8 | address candidate, 9 | bytes4 interfaceID 10 | ) internal returns (bool supportsInterface) { 11 | (bool success, bytes memory response) = candidate.call( 12 | abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceID) 13 | ); 14 | 15 | if (!success) { 16 | return false; 17 | } 18 | 19 | if (response.length == 0) { 20 | return false; 21 | } 22 | 23 | assembly { 24 | supportsInterface := mload(add(response, 32)) 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/utils/SafeCast.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * Utilities that convert numeric types avoiding silent overflows. 6 | */ 7 | import "./SafeCast/SafeCastU32.sol"; 8 | import "./SafeCast/SafeCastI32.sol"; 9 | import "./SafeCast/SafeCastI24.sol"; 10 | import "./SafeCast/SafeCastU56.sol"; 11 | import "./SafeCast/SafeCastI56.sol"; 12 | import "./SafeCast/SafeCastU64.sol"; 13 | import "./SafeCast/SafeCastI64.sol"; 14 | import "./SafeCast/SafeCastI128.sol"; 15 | import "./SafeCast/SafeCastI256.sol"; 16 | import "./SafeCast/SafeCastU128.sol"; 17 | import "./SafeCast/SafeCastU160.sol"; 18 | import "./SafeCast/SafeCastU256.sol"; 19 | import "./SafeCast/SafeCastAddress.sol"; 20 | import "./SafeCast/SafeCastBytes32.sol"; 21 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/utils/SafeCast/SafeCastAddress.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title See SafeCast.sol. 6 | */ 7 | library SafeCastAddress { 8 | function to256(address x) internal pure returns (uint256) { 9 | return uint256(uint160(x)); 10 | } 11 | 12 | function toBytes32(address x) internal pure returns (bytes32) { 13 | return bytes32(uint256(uint160(x))); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/utils/SafeCast/SafeCastBytes32.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title See SafeCast.sol. 6 | */ 7 | library SafeCastBytes32 { 8 | function toAddress(bytes32 x) internal pure returns (address) { 9 | return address(uint160(uint256(x))); 10 | } 11 | 12 | function toUint(bytes32 x) internal pure returns (uint) { 13 | return uint(x); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/utils/SafeCast/SafeCastI24.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title See SafeCast.sol. 6 | */ 7 | library SafeCastI24 { 8 | function to256(int24 x) internal pure returns (int256) { 9 | return int256(x); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/utils/SafeCast/SafeCastI32.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title See SafeCast.sol. 6 | */ 7 | library SafeCastI32 { 8 | error OverflowInt32ToUint32(); 9 | 10 | function toUint(int32 x) internal pure returns (uint32) { 11 | // ----------------------<========o========>---------------------- 12 | // ----------------------xxxxxxxxxo=========>---------------------- 13 | if (x < 0) { 14 | revert OverflowInt32ToUint32(); 15 | } 16 | 17 | return uint32(x); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/utils/SafeCast/SafeCastI56.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title See SafeCast.sol. 6 | */ 7 | library SafeCastI56 { 8 | error OverflowInt56ToInt24(); 9 | 10 | function to24(int56 x) internal pure returns (int24) { 11 | // ----------------------<========o========>----------------------- 12 | // ----------------------xxx<=====o=====>xxx----------------------- 13 | if (x < int256(type(int24).min) || x > int256(type(int24).max)) { 14 | revert OverflowInt56ToInt24(); 15 | } 16 | 17 | return int24(x); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/utils/SafeCast/SafeCastI64.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title See SafeCast.sol. 6 | */ 7 | library SafeCastI64 { 8 | error OverflowInt64ToUint64(); 9 | 10 | function toUint(int64 x) internal pure returns (uint64) { 11 | // ----------------------<========o========>---------------------- 12 | // ----------------------xxxxxxxxxo=========>---------------------- 13 | if (x < 0) { 14 | revert OverflowInt64ToUint64(); 15 | } 16 | 17 | return uint64(x); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/utils/SafeCast/SafeCastU160.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title See SafeCast.sol. 6 | */ 7 | library SafeCastU160 { 8 | function to256(uint160 x) internal pure returns (uint256) { 9 | return uint256(x); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/utils/SafeCast/SafeCastU32.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title See SafeCast.sol. 6 | */ 7 | library SafeCastU32 { 8 | error OverflowUint32ToInt32(); 9 | 10 | function toInt(uint32 x) internal pure returns (int32) { 11 | // -------------------------------o=========>---------------------- 12 | // ----------------------<========o========>x---------------------- 13 | if (x > uint32(type(int32).max)) { 14 | revert OverflowUint32ToInt32(); 15 | } 16 | 17 | return int32(x); 18 | } 19 | 20 | function to256(uint32 x) internal pure returns (uint256) { 21 | return uint256(x); 22 | } 23 | 24 | function to56(uint32 x) internal pure returns (uint56) { 25 | return uint56(x); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/utils/SafeCast/SafeCastU56.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title See SafeCast.sol. 6 | */ 7 | library SafeCastU56 { 8 | error OverflowUint56ToInt56(); 9 | 10 | function toInt(uint56 x) internal pure returns (int56) { 11 | // -------------------------------o=========>---------------------- 12 | // ----------------------<========o========>x---------------------- 13 | if (x > uint56(type(int56).max)) { 14 | revert OverflowUint56ToInt56(); 15 | } 16 | 17 | return int56(x); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /utils/core-contracts/contracts/utils/SafeCast/SafeCastU64.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title See SafeCast.sol. 6 | */ 7 | library SafeCastU64 { 8 | error OverflowUint64ToInt64(); 9 | 10 | function toInt(uint64 x) internal pure returns (int64) { 11 | // -------------------------------o=========>---------------------- 12 | // ----------------------<========o========>x---------------------- 13 | if (x > uint64(type(int64).max)) { 14 | revert OverflowUint64ToInt64(); 15 | } 16 | 17 | return int64(x); 18 | } 19 | 20 | function to256(uint64 x) internal pure returns (uint256) { 21 | return uint256(x); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /utils/core-contracts/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import commonConfig from '@synthetixio/common-config/hardhat.config'; 2 | 3 | import 'solidity-docgen'; 4 | import { templates } from '@synthetixio/docgen'; 5 | 6 | const config = { 7 | ...commonConfig, 8 | defaultNetwork: 'hardhat', 9 | docgen: { 10 | exclude: [ 11 | './errors', 12 | './generated', 13 | './initializable', 14 | './interfaces/external', 15 | './mocks', 16 | './ownership', 17 | './proxy', 18 | './token', 19 | './utils', 20 | ], 21 | templates, 22 | }, 23 | mocha: { 24 | timeout: 120000, 25 | }, 26 | }; 27 | 28 | export default config; 29 | -------------------------------------------------------------------------------- /utils/core-modules/.gitignore: -------------------------------------------------------------------------------- 1 | contracts/Router.sol 2 | contracts/routers 3 | deployments 4 | -------------------------------------------------------------------------------- /utils/core-modules/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require('@synthetixio/common-config/.solcover.js'), 3 | skipFiles: ['routers'], 4 | }; 5 | -------------------------------------------------------------------------------- /utils/core-modules/contracts/Proxy.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {UUPSProxyWithOwner} from "@synthetixio/core-contracts/contracts/proxy/UUPSProxyWithOwner.sol"; 5 | 6 | contract Proxy is UUPSProxyWithOwner { 7 | // solhint-disable-next-line no-empty-blocks 8 | constructor( 9 | address firstImplementation, 10 | address initialOwner 11 | ) UUPSProxyWithOwner(firstImplementation, initialOwner) {} 12 | } 13 | -------------------------------------------------------------------------------- /utils/core-modules/contracts/interfaces/IOwnerModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | /** 5 | * @title Module for giving a system owner based access control. 6 | */ 7 | // solhint-disable-next-line no-empty-blocks 8 | interface IOwnerModule { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /utils/core-modules/contracts/interfaces/ISampleFeatureFlagModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | interface ISampleFeatureFlagModule { 5 | function setFeatureFlaggedValue(uint256 valueToSet) external; 6 | 7 | function getFeatureFlaggedValue() external view returns (uint256); 8 | } 9 | -------------------------------------------------------------------------------- /utils/core-modules/contracts/interfaces/ISampleOwnedModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | interface ISampleOwnedModule { 5 | function setProtectedValue(uint256 newProtectedValue) external payable; 6 | 7 | function getProtectedValue() external view returns (uint256); 8 | } 9 | -------------------------------------------------------------------------------- /utils/core-modules/contracts/interfaces/external/IAny2EVMMessageReceiver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.4; 3 | 4 | import "../../utils/CcipClient.sol"; 5 | 6 | /// @notice Application contracts that intend to receive messages from 7 | /// the router should implement this interface. 8 | interface IAny2EVMMessageReceiver { 9 | /// @notice Router calls this to deliver a message. 10 | /// If this reverts, any token transfers also revert. The message 11 | /// will move to a FAILED state and become available for manual execution 12 | /// as a retry. Fees already paid are NOT currently refunded (may change). 13 | /// @param message CCIP Message 14 | /// @dev Note ensure you check the msg.sender is the router 15 | function ccipReceive(CcipClient.Any2EVMMessage calldata message) external; 16 | } 17 | -------------------------------------------------------------------------------- /utils/core-modules/contracts/modules/CcipReceiverModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/core-contracts/contracts/ownership/OwnableStorage.sol"; 5 | 6 | import "../interfaces/external/IAny2EVMMessageReceiver.sol"; 7 | import "../interfaces/IAssociatedSystemsModule.sol"; 8 | 9 | import "../storage/AssociatedSystem.sol"; 10 | import "../storage/CrossChain.sol"; 11 | 12 | /** 13 | * @title Module with assorted utility functions. 14 | * @dev See IUtilsModule. 15 | */ 16 | contract CcipReceiverModule is IAny2EVMMessageReceiver { 17 | function ccipReceive(CcipClient.Any2EVMMessage memory message) external { 18 | CrossChain.processCcipReceive(CrossChain.load(), message); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /utils/core-modules/contracts/modules/CoreModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {OwnerModule} from "./OwnerModule.sol"; 5 | import {UpgradeModule} from "./UpgradeModule.sol"; 6 | 7 | // solhint-disable-next-line no-empty-blocks 8 | contract CoreModule is OwnerModule, UpgradeModule { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /utils/core-modules/contracts/modules/OwnerModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/core-contracts/contracts/ownership/Ownable.sol"; 5 | import "@synthetixio/core-contracts/contracts/initializable/InitializableMixin.sol"; 6 | import "../interfaces/IOwnerModule.sol"; 7 | 8 | /** 9 | * @title Module for giving a system owner based access control. 10 | * See IOwnerModule. 11 | */ 12 | contract OwnerModule is Ownable, IOwnerModule { 13 | // solhint-disable-next-line no-empty-blocks 14 | constructor() Ownable(address(0)) { 15 | // empty intentionally 16 | } 17 | 18 | // no impl intentionally 19 | } 20 | -------------------------------------------------------------------------------- /utils/core-modules/contracts/modules/UpgradeModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/core-contracts/contracts/proxy/UUPSImplementation.sol"; 5 | import "@synthetixio/core-contracts/contracts/ownership/OwnableStorage.sol"; 6 | 7 | contract UpgradeModule is UUPSImplementation { 8 | function upgradeTo(address newImplementation) public override { 9 | OwnableStorage.onlyOwner(); 10 | _upgradeTo(newImplementation); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /utils/core-modules/contracts/modules/mocks/GenericModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | contract GenericModule { 5 | function getFortyTwo() public pure returns (uint256) { 6 | return 42; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /utils/core-modules/contracts/modules/mocks/SampleFeatureFlagModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "../../interfaces/ISampleFeatureFlagModule.sol"; 5 | import "../../storage/SampleStorage.sol"; 6 | import "../../storage/FeatureFlag.sol"; 7 | 8 | contract SampleFeatureFlagModule is ISampleFeatureFlagModule { 9 | function setFeatureFlaggedValue(uint256 valueToSet) external { 10 | FeatureFlag.ensureAccessToFeature("SAMPLE_FEATURE"); 11 | SampleStorage.load().someValue = valueToSet; 12 | } 13 | 14 | function getFeatureFlaggedValue() external view returns (uint256) { 15 | return SampleStorage.load().someValue; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /utils/core-modules/contracts/modules/mocks/SampleOwnedModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/core-contracts/contracts/ownership/OwnableStorage.sol"; 5 | import "../../storage/SampleStorage.sol"; 6 | import "../../interfaces/ISampleOwnedModule.sol"; 7 | 8 | contract SampleOwnedModule is ISampleOwnedModule { 9 | function setProtectedValue(uint256 newProtectedValue) public payable override { 10 | OwnableStorage.onlyOwner(); 11 | 12 | SampleStorage.load().protectedValue = newProtectedValue; 13 | } 14 | 15 | function getProtectedValue() public view override returns (uint256) { 16 | return SampleStorage.load().protectedValue; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /utils/core-modules/contracts/storage/Initialized.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | library Initialized { 5 | struct Data { 6 | bool initialized; 7 | } 8 | 9 | function load(bytes32 id) internal pure returns (Data storage store) { 10 | bytes32 s = keccak256(abi.encode("io.synthetix.code-modules.Initialized", id)); 11 | assembly { 12 | store.slot := s 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /utils/core-modules/contracts/storage/SampleStorage.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | library SampleStorage { 5 | bytes32 private constant _SLOT_SAMPLE_STORAGE = 6 | keccak256(abi.encode("io.synthetix.core-modules.Sample")); 7 | 8 | struct Data { 9 | uint256 someValue; 10 | uint256 protectedValue; 11 | } 12 | 13 | function load() internal pure returns (Data storage store) { 14 | bytes32 s = _SLOT_SAMPLE_STORAGE; 15 | assembly { 16 | store.slot := s 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /utils/core-modules/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import commonConfig from '@synthetixio/common-config/hardhat.config'; 2 | 3 | import 'solidity-docgen'; 4 | import { templates } from '@synthetixio/docgen'; 5 | 6 | const config = { 7 | ...commonConfig, 8 | docgen: { 9 | exclude: [ 10 | './interfaces/external', 11 | './mocks', 12 | './modules', 13 | './storage', 14 | './utils', 15 | './Proxy.sol', 16 | ], 17 | templates, 18 | }, 19 | mocha: { 20 | timeout: 120000, 21 | }, 22 | }; 23 | 24 | export default config; 25 | -------------------------------------------------------------------------------- /utils/core-utils/.gitignore: -------------------------------------------------------------------------------- 1 | /utils 2 | -------------------------------------------------------------------------------- /utils/core-utils/.mocharc.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec": ["test/**/*.test.ts"], 3 | "timeout": 10000, 4 | "watch-files": ["utils/**/*.ts", "test/**/*.ts"] 5 | } 6 | -------------------------------------------------------------------------------- /utils/core-utils/.nycrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@istanbuljs/nyc-config-typescript", 3 | "all": true, 4 | "include": ["src/utils/**/*.ts"], 5 | "check-coverage": true, 6 | "reporter": ["lcov", "text"], 7 | "branches": 31, 8 | "lines": 25, 9 | "functions": 11, 10 | "statements": 24 11 | } 12 | -------------------------------------------------------------------------------- /utils/core-utils/src/globals.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | const window: undefined; 3 | } 4 | 5 | export {}; 6 | -------------------------------------------------------------------------------- /utils/core-utils/src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": ".", 6 | "outDir": "..", 7 | "composite": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /utils/core-utils/src/types.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'pako'; 2 | declare module 'debug'; 3 | -------------------------------------------------------------------------------- /utils/core-utils/src/utils/assertions/assert-address.ts: -------------------------------------------------------------------------------- 1 | import assert from 'node:assert/strict'; 2 | import { ethers } from 'ethers'; 3 | 4 | type Addressish = string | `0x${string}` | ethers.BigNumberish; 5 | 6 | export function addressEqual(address1: Addressish, address2: Addressish) { 7 | return ( 8 | ethers.utils.getAddress(address1 as string) === ethers.utils.getAddress(address2 as string) 9 | ); 10 | } 11 | 12 | export function assertAddress(address: Addressish) { 13 | assert.ok(ethers.utils.isAddress(address as string), `Invalid address: ${address}`); 14 | } 15 | 16 | export function assertAddressEqual(address1: Addressish, address2: Addressish) { 17 | assert.equal( 18 | ethers.utils.getAddress(address1 as string), 19 | ethers.utils.getAddress(address2 as string) 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /utils/core-utils/src/utils/bootstrap/cannon-node.ts: -------------------------------------------------------------------------------- 1 | import { AnvilServer } from '@foundry-rs/hardhat-anvil/dist/src/anvil-server'; 2 | 3 | interface NodeOptions { 4 | port?: number; 5 | chainId?: number; 6 | } 7 | 8 | export async function launchCannonNode(options: NodeOptions = {}) { 9 | if (typeof options.port === 'undefined' || options.port === 0) { 10 | const { default: getPort } = await import('get-port'); 11 | options.port = await getPort(); 12 | } 13 | 14 | const { port } = options; 15 | const server = await AnvilServer.launch({ launch: true, ...options }, false); 16 | const rpcUrl = `http://127.0.0.1:${port}/`; 17 | 18 | return { server, port, rpcUrl }; 19 | } 20 | -------------------------------------------------------------------------------- /utils/core-utils/src/utils/ethers/bignumber.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'ethers'; 2 | 3 | export const BN_ONE = ethers.BigNumber.from(1); 4 | export const BN_TWO = ethers.BigNumber.from(2); 5 | 6 | export function bnSqrt(value: ethers.BigNumber) { 7 | let z = value.add(BN_ONE).div(BN_TWO); 8 | let y = value; 9 | 10 | while (z.sub(y).isNegative()) { 11 | y = z; 12 | z = value.div(z).add(z).div(BN_TWO); 13 | } 14 | 15 | return y; 16 | } 17 | -------------------------------------------------------------------------------- /utils/core-utils/src/utils/ethers/provider.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'ethers'; 2 | 3 | /** 4 | * Manually parses raw event logs with the given contract interface 5 | * @param {contract} contract The contract to use for identifying the logs 6 | * @param {logs} logs An array of raw unparsed logs 7 | * @returns {array} The array of parsed events 8 | */ 9 | export async function getBlockTimestamp( 10 | provider: ethers.providers.Provider, 11 | block: ethers.providers.BlockTag | Promise = 'latest' 12 | ) { 13 | return (await provider.getBlock(block)).timestamp; 14 | } 15 | -------------------------------------------------------------------------------- /utils/core-utils/src/utils/misc/array.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Filter all the values from an array to get only repeated ones 3 | * e.g.: [1, 1, 2, 3].filter(onlyRepeated) // => [1] 4 | */ 5 | export function onlyRepeated(value: T, index: number, self: T[]) { 6 | const last = self.lastIndexOf(value); 7 | return self.indexOf(value) !== last && index === last; 8 | } 9 | 10 | /** 11 | * Filter all the values from an array to get only unique ones 12 | * e.g.: [1, 1, 2, 3].filter(onlyUnique) // => [1, 2, 3] 13 | */ 14 | export function onlyUnique(value: T, index: number, self: T[]) { 15 | return self.indexOf(value) === index; 16 | } 17 | -------------------------------------------------------------------------------- /utils/core-utils/src/utils/misc/clone.ts: -------------------------------------------------------------------------------- 1 | import rfdc from 'rfdc'; 2 | 3 | export function clone(objectToClone: T): T { 4 | return rfdc()(objectToClone); 5 | } 6 | -------------------------------------------------------------------------------- /utils/core-utils/src/utils/misc/dates.ts: -------------------------------------------------------------------------------- 1 | export function getUnixTimestamp(date = new Date()) { 2 | return Math.floor(date.getTime() / 1000); 3 | } 4 | 5 | export function fromUnixTimestamp(timestamp: number) { 6 | return new Date(timestamp * 1000); 7 | } 8 | 9 | export const daysToSeconds = (days: number) => days * 3600 * 24; 10 | -------------------------------------------------------------------------------- /utils/core-utils/src/utils/misc/git.ts: -------------------------------------------------------------------------------- 1 | import child_process from 'child_process'; 2 | 3 | const execSync = (cmd: string) => child_process.execSync(cmd).toString().trim(); 4 | 5 | export function getCommit() { 6 | return execSync('git rev-parse HEAD'); 7 | } 8 | 9 | export function getBranch() { 10 | return execSync('git rev-parse --abbrev-ref HEAD'); 11 | } 12 | -------------------------------------------------------------------------------- /utils/core-utils/src/utils/misc/strings.ts: -------------------------------------------------------------------------------- 1 | export function capitalize(value: string) { 2 | return value.charAt(0).toUpperCase() + value.slice(1); 3 | } 4 | -------------------------------------------------------------------------------- /utils/core-utils/src/utils/mocha/mocha-helpers.ts: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | import { Context } from 'mocha'; 3 | 4 | export function printGasUsed({ test, gasUsed }: { test: Context; gasUsed: number }) { 5 | test.runnable().title = `${test.runnable().title} (${chalk.green(gasUsed)}${chalk.gray(' gas)')}`; 6 | } 7 | -------------------------------------------------------------------------------- /utils/core-utils/test/fixtures/event-abi.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | anonymous: false, 4 | inputs: [ 5 | { 6 | indexed: false, 7 | internalType: 'address', 8 | name: 'sender', 9 | type: 'address', 10 | }, 11 | ], 12 | name: 'Test', 13 | type: 'event', 14 | }, 15 | ]; 16 | -------------------------------------------------------------------------------- /utils/core-utils/test/fixtures/no-contract-ast.json: -------------------------------------------------------------------------------- 1 | { 2 | "absolutePath": "contracts/modules/AnotherModule.sol", 3 | "exportedSymbols": {}, 4 | "id": 621, 5 | "license": "Unlicense", 6 | "nodeType": "SourceUnit", 7 | "nodes": [ 8 | { 9 | "id": 599, 10 | "literals": ["solidity", "^", "0.8", ".0"], 11 | "nodeType": "PragmaDirective", 12 | "src": "37:23:10" 13 | } 14 | ], 15 | "src": "37:1165:10" 16 | } 17 | -------------------------------------------------------------------------------- /utils/core-utils/test/fixtures/require-all-example/1-one.ts: -------------------------------------------------------------------------------- 1 | export default 1; 2 | -------------------------------------------------------------------------------- /utils/core-utils/test/fixtures/require-all-example/2-two.json: -------------------------------------------------------------------------------- 1 | 2 2 | -------------------------------------------------------------------------------- /utils/core-utils/test/fixtures/require-all-example/3-three.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Synthetixio/synthetix-v3/d795f6dcdcbc644f8dfbc684903c56f9b6e751e2/utils/core-utils/test/fixtures/require-all-example/3-three.yml -------------------------------------------------------------------------------- /utils/core-utils/test/fixtures/sample-project/contracts/AnotherModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | // solhint-disable-next-line no-empty-blocks 5 | contract AnotherModule {} 6 | -------------------------------------------------------------------------------- /utils/core-utils/test/fixtures/sample-project/contracts/MultipleInheritance.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | // solhint-disable one-contract-per-file 3 | pragma solidity >=0.8.11 <0.9.0; 4 | 5 | import {AnotherModule} from "./AnotherModule.sol"; 6 | import {SampleModule as AliasedModule} from "./SampleModule.sol"; 7 | 8 | // solhint-disable-next-line no-empty-blocks 9 | contract SomeModule is AnotherModule {} 10 | 11 | // solhint-disable-next-line no-empty-blocks 12 | contract MultipleInheritancce is SomeModule, AliasedModule {} 13 | -------------------------------------------------------------------------------- /utils/core-utils/test/fixtures/sample-project/contracts/SampleModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | // solhint-disable-next-line no-empty-blocks 5 | contract SampleModule {} 6 | -------------------------------------------------------------------------------- /utils/core-utils/test/fixtures/sample-project/contracts/Token.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | // solhint-disable one-contract-per-file 3 | pragma solidity >=0.8.11 <0.9.0; 4 | 5 | import "@synthetixio/core-contracts/contracts/token/ERC20.sol"; 6 | import {ERC721 as ERC721Base} from "@synthetixio/core-contracts/contracts/token/ERC721.sol"; 7 | 8 | contract Token is ERC20 { 9 | constructor(string memory name) { 10 | _initialize(name, "T", 0); 11 | } 12 | } 13 | 14 | contract AnotherToken is ERC721Base { 15 | constructor(string memory name) { 16 | _initialize(name, "T", "ipfs://abc"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /utils/core-utils/test/fixtures/sample-project/contracts/TokenModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {Token as BaseToken} from "./Token.sol"; 5 | 6 | contract TokenModule { 7 | address[] private _tokens; 8 | 9 | function createToken(string memory name) external { 10 | BaseToken token = new BaseToken(name); 11 | _tokens.push(address(token)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /utils/core-utils/test/fixtures/sample-project/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | solidity: '0.8.17', 3 | }; 4 | -------------------------------------------------------------------------------- /utils/core-utils/test/utils/ethers/bignumber.test.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'ethers'; 2 | 3 | import assertBn from '../../../src/utils/assertions/assert-bignumber'; 4 | import { bnSqrt } from '../../../src/utils/ethers/bignumber'; 5 | 6 | describe('utils/ethers/bignumber.ts', function () { 7 | it('can calculate square roots', async function () { 8 | assertBn.equal(bnSqrt(ethers.BigNumber.from(0)), 0); 9 | assertBn.equal(bnSqrt(ethers.BigNumber.from(4)), 2); 10 | assertBn.equal(bnSqrt(ethers.BigNumber.from(123456789)), 11111); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /utils/core-utils/test/utils/misc/array.test.ts: -------------------------------------------------------------------------------- 1 | import { deepEqual } from 'assert/strict'; 2 | import { onlyRepeated, onlyUnique } from '../../../src/utils/misc/array'; 3 | 4 | describe('utils/misc/array.ts', function () { 5 | describe('#onlyRepeated', function () { 6 | it('leaves one instance of repeated values', function () { 7 | deepEqual([2, null], [1, 2, 2, 3, null, null, null].filter(onlyRepeated)); 8 | }); 9 | }); 10 | 11 | describe('#onlyUnique', function () { 12 | it('leaves only unqiue values', function () { 13 | deepEqual([1, 2, 3, null], [1, 2, 2, 3, null, null, null].filter(onlyUnique)); 14 | }); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /utils/core-utils/test/utils/misc/git.test.ts: -------------------------------------------------------------------------------- 1 | import assert from 'assert/strict'; 2 | import child_process from 'child_process'; 3 | 4 | import { getBranch, getCommit } from '../../../src/utils/misc/git'; 5 | 6 | const execSync = (cmd: string) => child_process.execSync(cmd).toString().trim(); 7 | 8 | describe('utils/misc/git.ts', function () { 9 | it('can retrieve the current commit', function () { 10 | assert.equal(getCommit(), execSync('git rev-parse HEAD')); 11 | }); 12 | 13 | it('can retrieve the current branch', function () { 14 | assert.equal(getBranch(), execSync('git rev-parse --abbrev-ref HEAD')); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /utils/core-utils/test/utils/misc/strings.test.ts: -------------------------------------------------------------------------------- 1 | import { equal } from 'assert/strict'; 2 | 3 | import { capitalize } from '../../../src/utils/misc/strings'; 4 | 5 | describe('utils/misc/strings.ts', function () { 6 | it('returns the strings with the correct format', function () { 7 | equal(capitalize('someText'), 'SomeText'); 8 | equal(capitalize('SomeText'), 'SomeText'); 9 | equal(capitalize('sOmeText'), 'SOmeText'); 10 | equal(capitalize('SOmeText'), 'SOmeText'); 11 | 12 | equal(capitalize('s'), 'S'); 13 | equal(capitalize('S'), 'S'); 14 | 15 | equal(capitalize('1number'), '1number'); 16 | equal(capitalize('_otherValue'), '_otherValue'); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /utils/core-utils/test/utils/mocha/mocha-helpers.test.ts: -------------------------------------------------------------------------------- 1 | import assert from 'assert/strict'; 2 | import chalk from 'chalk'; 3 | import { Context } from 'mocha'; 4 | 5 | import { printGasUsed } from '../../../src/utils/mocha/mocha-helpers'; 6 | 7 | describe('utils/tests.ts', function () { 8 | it('can print the gas used in a test', function () { 9 | const test = { 10 | _runnable: { 11 | title: 'Hello', 12 | }, 13 | runnable: () => test._runnable, 14 | }; 15 | 16 | const gasUsed = 1337; 17 | printGasUsed({ 18 | test: test as unknown as Context, 19 | gasUsed, 20 | }); 21 | 22 | assert.equal(test._runnable.title, `Hello (${chalk.green(gasUsed)}${chalk.gray(' gas)')}`); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /utils/deps/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-console": "off" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /utils/deps/lib/colors.js: -------------------------------------------------------------------------------- 1 | exports.fgReset = '\x1b[0m'; 2 | exports.fgRed = '\x1b[31m'; 3 | exports.fgGreen = '\x1b[32m'; 4 | exports.fgYellow = '\x1b[33m'; 5 | exports.fgCyan = '\x1b[36m'; 6 | -------------------------------------------------------------------------------- /utils/deps/lib/exec.js: -------------------------------------------------------------------------------- 1 | module.exports = async function exec(cmd, options) { 2 | return new Promise((resolve, reject) => 3 | require('child_process').exec( 4 | cmd, 5 | { encoding: 'utf-8', stdio: 'pipe', ...options }, 6 | (error, data) => (error ? reject(error) : resolve(data.trim())) 7 | ) 8 | ); 9 | }; 10 | -------------------------------------------------------------------------------- /utils/deps/lib/workspaces.js: -------------------------------------------------------------------------------- 1 | module.exports = async function workspaces() { 2 | const exec = require('./exec'); 3 | return (await exec('yarn workspaces list --verbose --json')) 4 | .split('\n') 5 | .filter(Boolean) 6 | .map((line) => JSON.parse(line)); 7 | }; 8 | -------------------------------------------------------------------------------- /utils/deps/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@synthetixio/deps", 3 | "private": true, 4 | "version": "1.0.0", 5 | "author": "Nikita ", 6 | "repository": "github:Synthetixio/js-monorepo", 7 | "license": "MIT", 8 | "bin": { 9 | "deps": "./deps.js", 10 | "deps-circular": "./circular.js", 11 | "deps-mismatched": "./mismatched.js" 12 | }, 13 | "devDependencies": { 14 | "depcheck": "^1.4.7", 15 | "prettier": "^3.2.5", 16 | "typescript": "^5.5.4" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /utils/docgen/.gitignore: -------------------------------------------------------------------------------- 1 | abis/ 2 | docs/ 3 | deployments/ 4 | -------------------------------------------------------------------------------- /utils/docgen/index.d.ts: -------------------------------------------------------------------------------- 1 | export declare const templates: string; 2 | -------------------------------------------------------------------------------- /utils/docgen/index.js: -------------------------------------------------------------------------------- 1 | const { join } = require('path'); 2 | 3 | exports.templates = join(__dirname, 'natspec/theme'); 4 | -------------------------------------------------------------------------------- /utils/docgen/natspec/theme/common.hbs: -------------------------------------------------------------------------------- 1 | {{h}}{{formatTitle name}} 2 | 3 | {{#if signature}} 4 | ```solidity 5 | {{{signature}}} 6 | ``` 7 | {{/if}} 8 | 9 | {{#if natspec.notice}} 10 | {{{natspec.notice}}} 11 | {{/if}} 12 | 13 | {{#if natspec.dev}} 14 | {{{natspec.dev}}} 15 | {{/if}} 16 | 17 | {{#if natspec.params}} 18 | **Parameters** 19 | {{#each params}} 20 | * `{{name}}` (*{{type}}*) - {{{joinLines natspec}}} 21 | {{/each}} 22 | {{/if}} 23 | 24 | {{#if natspec.returns}} 25 | **Returns** 26 | {{#each returns}} 27 | * `{{#if name}}{{name}}{{else}}[{{@index}}]{{/if}}` (*{{type}}*) - {{{joinLines 28 | natspec 29 | }}} 30 | {{/each}} 31 | {{/if}} 32 | -------------------------------------------------------------------------------- /utils/docgen/natspec/theme/contract.hbs: -------------------------------------------------------------------------------- 1 | {{h}}{{formatTitle name}} 2 | 3 | {{#each (inheritedFunctions)}} 4 | {{#hsection}} 5 | {{>item}} 6 | {{/hsection}} 7 | {{/each}} 8 | 9 | {{#each (inheritedEvents)}} 10 | {{#hsection}} 11 | {{>item}} 12 | {{/hsection}} 13 | {{/each}} 14 | -------------------------------------------------------------------------------- /utils/docgen/natspec/theme/page.hbs: -------------------------------------------------------------------------------- 1 | {{#each items}} 2 | {{#hsection}} 3 | {{>item}} 4 | {{/hsection}} 5 | 6 | {{/each}} 7 | -------------------------------------------------------------------------------- /utils/docgen/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@synthetixio/docgen", 3 | "private": true, 4 | "version": "1.0.0", 5 | "repository": "github:Synthetixio/js-monorepo", 6 | "license": "MIT", 7 | "main": "index.js", 8 | "types": "index.d.ts", 9 | "scripts": { 10 | "abis": "node ./abis.js", 11 | "docgen:contracts": "./docgen-contracts.sh" 12 | }, 13 | "devDependencies": { 14 | "handlebars": "^4.7.8", 15 | "solidity-ast": "^0.4.55", 16 | "solidity-docgen": "^0.6.0-beta.36" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /utils/eslint-plugin-progress/index.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | const CWD = process.cwd(); 4 | 5 | function create(context) { 6 | const filename = context.getFilename(); 7 | const relativeFilePath = path.relative(CWD, filename); 8 | 9 | console.log('Checked:', relativeFilePath); 10 | return {}; 11 | } 12 | 13 | module.exports = { 14 | rules: { 15 | enable: { 16 | create, 17 | }, 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /utils/eslint-plugin-progress/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-plugin-progress", 3 | "private": true, 4 | "version": "1.0.0", 5 | "main": "index.js" 6 | } 7 | -------------------------------------------------------------------------------- /utils/hardhat-storage/jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { JestConfigWithTsJest } from 'ts-jest'; 2 | 3 | const jestConfig: JestConfigWithTsJest = { 4 | preset: 'ts-jest', 5 | moduleFileExtensions: ['js', 'ts', 'json', 'sol'], 6 | collectCoverageFrom: ['./src/**/*.ts'], 7 | }; 8 | 9 | export default jestConfig; 10 | -------------------------------------------------------------------------------- /utils/hardhat-storage/src/index.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import { extendConfig } from 'hardhat/config'; 3 | import { HardhatConfig, HardhatUserConfig } from 'hardhat/types'; 4 | import './type-extensions'; 5 | import './subtasks/generate-testable-storage'; 6 | import './subtasks/get-artifacts'; 7 | import './subtasks/validate-contracts'; 8 | import './subtasks/verify-contracts'; 9 | import './tasks/dump'; 10 | import './tasks/generate-testable'; 11 | import './tasks/layout'; 12 | import './tasks/validate'; 13 | import './tasks/verify'; 14 | 15 | extendConfig((config: HardhatConfig, userConfig: Readonly) => { 16 | config.storage = { 17 | artifacts: userConfig.storage?.artifacts || [path.join(config.paths.sources, '**')], 18 | }; 19 | }); 20 | -------------------------------------------------------------------------------- /utils/hardhat-storage/src/internal/are-deep-equal.ts: -------------------------------------------------------------------------------- 1 | import { deepEqual } from 'node:assert'; 2 | 3 | export function areDeepEqual(a: unknown, b: unknown) { 4 | try { 5 | deepEqual(a, b); 6 | return true; 7 | } catch { 8 | return false; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /utils/hardhat-storage/src/internal/is-present.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Helper function intended to be used as [].filter(isPresent) to remove all 3 | * unexistant values from an array. 4 | */ 5 | export function isPresent(val: T): val is NonNullable { 6 | return val !== null && typeof val !== 'undefined'; 7 | } 8 | -------------------------------------------------------------------------------- /utils/hardhat-storage/src/internal/log-in-chunks.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Helper function to write output to the console, uses process.stdout.write and 3 | * write in chunks because bash piping seems to have some sort of a problem with 4 | * outputting huge amounts of data all at once while using pipes. 5 | */ 6 | export function logInChunks(data: unknown) { 7 | const _data = typeof data === 'string' ? data : JSON.stringify(data, null, 2); 8 | const chunkSize = 16; 9 | 10 | for (let i = 0; i < _data.length; i += chunkSize) { 11 | process.stdout.write(_data.slice(i, i + chunkSize)); 12 | } 13 | 14 | return _data; 15 | } 16 | -------------------------------------------------------------------------------- /utils/hardhat-storage/src/internal/path-helpers.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | 3 | export function ensureTrailingSlash(basePath: string) { 4 | basePath = path.normalize(basePath); 5 | return basePath.endsWith(path.sep) ? basePath : `${basePath}${path.sep}`; 6 | } 7 | 8 | export function removeBasePath(basePath: string, fullPath: string) { 9 | basePath = path.normalize(basePath); 10 | fullPath = path.normalize(fullPath); 11 | 12 | if (!basePath.endsWith(path.sep)) basePath += path.sep; 13 | 14 | if (!fullPath.startsWith(basePath)) { 15 | throw new Error(`The path "${fullPath}" is not inside "${fullPath}"`); 16 | } 17 | 18 | return fullPath.substring(basePath.length); 19 | } 20 | 21 | export function isExplicitRelativePath(sourceName: string) { 22 | return sourceName.startsWith('./') || sourceName.startsWith('../'); 23 | } 24 | -------------------------------------------------------------------------------- /utils/hardhat-storage/src/internal/quiet-compile.ts: -------------------------------------------------------------------------------- 1 | import { TASK_COMPILE } from 'hardhat/builtin-tasks/task-names'; 2 | import { HardhatRuntimeEnvironment } from 'hardhat/types'; 3 | 4 | /* 5 | * Note: Even though hardhat's compile task has a quiet option, 6 | * it still prints some output. This is a hack to completely silence 7 | * output during compile task run. 8 | */ 9 | export async function quietCompile(hre: HardhatRuntimeEnvironment, quiet: boolean) { 10 | let logCache; 11 | 12 | if (quiet) { 13 | logCache = console.log; 14 | console.log = () => {}; 15 | } 16 | 17 | try { 18 | await hre.run(TASK_COMPILE, { force: true, quiet: true }); 19 | } finally { 20 | if (logCache) console.log = logCache; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /utils/hardhat-storage/src/internal/render-template.ts: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs'; 2 | import Mustache from 'mustache'; 3 | 4 | export function renderTemplate(filepath: string, data: { [k: string]: unknown } = {}) { 5 | const template = fs.readFileSync(filepath).toString(); 6 | return Mustache.render(template, data); 7 | } 8 | -------------------------------------------------------------------------------- /utils/hardhat-storage/src/subtasks/get-artifacts.ts: -------------------------------------------------------------------------------- 1 | import { filterContracts } from '@synthetixio/core-utils/utils/hardhat/contracts'; 2 | import { subtask } from 'hardhat/config'; 3 | import { readHardhatArtifact } from '../internal/read-hardhat-artifact'; 4 | import { SUBTASK_GET_ARTIFACTS } from '../task-names'; 5 | import { GetArtifactFunction } from '../types'; 6 | 7 | type Result = { 8 | contracts: string[]; 9 | getArtifact: GetArtifactFunction; 10 | }; 11 | 12 | subtask(SUBTASK_GET_ARTIFACTS).setAction(async (_, hre) => { 13 | const allFqNames = await hre.artifacts.getAllFullyQualifiedNames(); 14 | const contracts = filterContracts(allFqNames, hre.config.storage.artifacts); 15 | const getArtifact = (fqName: string) => readHardhatArtifact(hre, fqName); 16 | return { contracts, getArtifact } satisfies Result; 17 | }); 18 | -------------------------------------------------------------------------------- /utils/hardhat-storage/src/task-names.ts: -------------------------------------------------------------------------------- 1 | export const SUBTASK_GENERATE_TESTABLE_STORAGE = 'storage:generate-testable-storage'; 2 | export const SUBTASK_GET_ARTIFACTS = 'storage:get-artifacts'; 3 | export const SUBTASK_VALIDATE_CONTRACTS = 'storage:validate-contracts'; 4 | export const SUBTASK_VERIFY_CONTRACTS = 'storage:verify-contracts'; 5 | export const TASK_GENERATE_TESTABLE = 'generate-testable'; 6 | export const TASK_STORAGE_DUMP = 'storage:dump'; 7 | export const TASK_STORAGE_LAYOUT = 'storage:layout'; 8 | export const TASK_STORAGE_VALIDATE = 'storage:validate'; 9 | export const TASK_STORAGE_VERIFY = 'storage:verify'; 10 | -------------------------------------------------------------------------------- /utils/hardhat-storage/src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": ".", 6 | "outDir": "../dist", 7 | "composite": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /utils/hardhat-storage/src/type-extensions.ts: -------------------------------------------------------------------------------- 1 | declare module 'hardhat/types/config' { 2 | export interface HardhatUserConfig { 3 | storage?: { 4 | artifacts?: string[]; 5 | }; 6 | } 7 | 8 | export interface HardhatConfig { 9 | storage: { 10 | artifacts: string[]; 11 | }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /utils/hardhat-storage/test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": ".." 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /utils/sample-project/.gitignore: -------------------------------------------------------------------------------- 1 | artifacts 2 | cache 3 | deployments/local 4 | deployments/hardhat 5 | contracts/routers 6 | Router.sol 7 | -------------------------------------------------------------------------------- /utils/sample-project/contracts/Proxy.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {UUPSProxyWithOwner} from "@synthetixio/core-contracts/contracts/proxy/UUPSProxyWithOwner.sol"; 5 | 6 | contract Proxy is UUPSProxyWithOwner { 7 | // solhint-disable-next-line no-empty-blocks 8 | constructor( 9 | address firstImplementation, 10 | address initialOwner 11 | ) UUPSProxyWithOwner(firstImplementation, initialOwner) {} 12 | } 13 | -------------------------------------------------------------------------------- /utils/sample-project/contracts/interfaces/IAnotherModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | interface IAnotherModule { 5 | function getAnotherValue() external pure returns (uint256); 6 | 7 | function getAnotherImmutableValue() external pure returns (uint256); 8 | } 9 | -------------------------------------------------------------------------------- /utils/sample-project/contracts/interfaces/IInitializableModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | interface IInitializableModule { 5 | function isInitializableModuleInitialized() external view returns (bool); 6 | 7 | function initializeInitializableModule() external; 8 | } 9 | -------------------------------------------------------------------------------- /utils/sample-project/contracts/interfaces/INewModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | interface INewModule { 5 | function setSomeNewValue(uint256 newValue) external; 6 | } 7 | -------------------------------------------------------------------------------- /utils/sample-project/contracts/interfaces/ISettingsModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | interface ISettingsModule { 5 | function getASettingValue() external view returns (uint256); 6 | 7 | function setASettingValue(uint256 newSettingValue) external; 8 | } 9 | -------------------------------------------------------------------------------- /utils/sample-project/contracts/interfaces/ISomeModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | interface ISomeModule { 5 | function getValue() external view returns (uint256); 6 | 7 | function getSomeValue() external view returns (uint256); 8 | 9 | function setValue(uint256 newValue) external; 10 | 11 | function setSomeValue(uint256 newSomeValue) external; 12 | } 13 | -------------------------------------------------------------------------------- /utils/sample-project/contracts/interfaces/ISomeModuleModified.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | interface ISomeModuleModified { 5 | function setValue(uint256 newValue) external; 6 | 7 | function setSomeValue(uint256 newSomeValue) external; 8 | 9 | function getValue() external view returns (uint256); 10 | 11 | function getSomeValue() external view returns (uint256); 12 | 13 | function fourtyTwo() external pure returns (uint256); 14 | } 15 | -------------------------------------------------------------------------------- /utils/sample-project/contracts/interfaces/ITokenModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | interface ITokenModule { 5 | function createSampleToken(bytes32 name) external; 6 | } 7 | -------------------------------------------------------------------------------- /utils/sample-project/contracts/modules/AnotherModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "../interfaces/IAnotherModule.sol"; 5 | 6 | contract AnotherModule is IAnotherModule { 7 | uint256 private constant _SIXTY_FOUR = 64; 8 | // solhint-disable-next-line immutable-vars-naming 9 | uint256 private immutable _LEET = 1337; 10 | 11 | function getAnotherValue() public pure override returns (uint256) { 12 | return _SIXTY_FOUR; 13 | } 14 | 15 | function getAnotherImmutableValue() public pure override returns (uint256) { 16 | return _LEET; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /utils/sample-project/contracts/modules/CoreModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import {CoreModule as BaseCoreModule} from "@synthetixio/core-modules/contracts/modules/CoreModule.sol"; 5 | 6 | // solhint-disable-next-line no-empty-blocks 7 | contract CoreModule is BaseCoreModule {} 8 | -------------------------------------------------------------------------------- /utils/sample-project/contracts/modules/InitializableModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/core-contracts/contracts/initializable/InitializableMixin.sol"; 5 | import "../storage/InitializableStorage.sol"; 6 | import "../interfaces/IInitializableModule.sol"; 7 | 8 | contract InitializableModule is InitializableStorage, InitializableMixin, IInitializableModule { 9 | function _isInitialized() internal view override returns (bool) { 10 | return _initializableStore().initialized; 11 | } 12 | 13 | function isInitializableModuleInitialized() external view override returns (bool) { 14 | return _isInitialized(); 15 | } 16 | 17 | function initializeInitializableModule() external override onlyIfNotInitialized { 18 | _initializableStore().initialized = true; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /utils/sample-project/contracts/modules/SettingsModule.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/core-contracts/contracts/ownership/OwnableStorage.sol"; 5 | import "../storage/SettingsStorage.sol"; 6 | import "../interfaces/ISettingsModule.sol"; 7 | 8 | contract SettingsModule is SettingsStorage, ISettingsModule { 9 | function setASettingValue(uint256 newSettingValue) public override { 10 | OwnableStorage.onlyOwner(); 11 | _settingsStore().aSettingValue = newSettingValue; 12 | } 13 | 14 | function getASettingValue() public view override returns (uint256) { 15 | return _settingsStore().aSettingValue; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /utils/sample-project/contracts/storage/GlobalStorage.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | contract GlobalStorage { 5 | bytes32 private constant _SLOT_GLOBAL_STORAGE = 6 | keccak256(abi.encode("io.synthetix.sample-project.Global")); 7 | 8 | struct GlobalStore { 9 | uint256 value; 10 | uint256 someValue; 11 | } 12 | 13 | function _globalStore() internal pure returns (GlobalStore storage store) { 14 | bytes32 s = _SLOT_GLOBAL_STORAGE; 15 | assembly { 16 | store.slot := s 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /utils/sample-project/contracts/storage/InitializableStorage.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | contract InitializableStorage { 5 | bytes32 private constant _SLOT_INITIALIZABLE_STORAGE = 6 | keccak256(abi.encode("io.synthetix.sample-project.Initializable")); 7 | 8 | struct InitializableStore { 9 | bool initialized; 10 | } 11 | 12 | function _initializableStore() internal pure returns (InitializableStore storage store) { 13 | bytes32 s = _SLOT_INITIALIZABLE_STORAGE; 14 | assembly { 15 | store.slot := s 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /utils/sample-project/contracts/storage/SettingsStorage.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | contract SettingsStorage { 5 | bytes32 private constant _SLOT_SETTINGS_STORAGE = 6 | keccak256(abi.encode("io.synthetix.sample-project.Settings")); 7 | 8 | struct SettingsStore { 9 | uint256 aSettingValue; 10 | } 11 | 12 | function _settingsStore() internal pure returns (SettingsStore storage store) { 13 | bytes32 s = _SLOT_SETTINGS_STORAGE; 14 | assembly { 15 | store.slot := s 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /utils/sample-project/contracts/test/Destroyer.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.11 <0.9.0; 3 | 4 | import "@synthetixio/core-contracts/contracts/proxy/ProxyStorage.sol"; 5 | 6 | contract Destroyer is ProxyStorage { 7 | function upgradeTo(address) public { 8 | _proxyStore().implementation = address(0); 9 | 10 | selfdestruct(payable(0)); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /utils/sample-project/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require('@nomiclabs/hardhat-ethers'); 2 | require('hardhat-cannon'); 3 | require('@synthetixio/hardhat-storage'); 4 | require('solidity-coverage'); 5 | 6 | module.exports = { 7 | solidity: { 8 | version: '0.8.17', 9 | settings: { 10 | optimizer: { 11 | enabled: true, 12 | runs: 200, 13 | }, 14 | }, 15 | }, 16 | defaultNetwork: 'cannon', 17 | storage: { 18 | artifacts: [ 19 | 'contracts/**', 20 | '!contracts/routers/**', 21 | '!contracts/generated/**', 22 | '!contracts/mocks/**', 23 | ], 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /utils/sample-project/test/bootstrap.js: -------------------------------------------------------------------------------- 1 | const { coreBootstrap } = require('@synthetixio/core-utils/utils/tests'); 2 | 3 | const result = coreBootstrap(); 4 | 5 | const restoreSnapshot = result.createSnapshot(); 6 | 7 | module.exports = function sampleProjectBootstrap() { 8 | before(async function loadSnapshot() { 9 | await restoreSnapshot(); 10 | }); 11 | 12 | return result; 13 | }; 14 | --------------------------------------------------------------------------------