├── .env.sample ├── .gitattributes ├── .github ├── PULL_REQUEST_TEMPLATE.md ├── autolabeler.yml ├── dependabot.yml ├── stale.yml └── workflows │ ├── check-pr-title.yml │ ├── ci.yml │ ├── publish.yml │ └── release.yml ├── .gitignore ├── .gitmodules ├── .husky ├── .gitignore └── pre-commit ├── .nvmrc ├── .prettierrc ├── .solcover.js ├── .solhint.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── contracts ├── examples │ └── helpers │ │ ├── HGetDragoData.sol │ │ ├── HGetMultipleBalances.sol │ │ └── HGetPools.sol ├── governance │ ├── IRigoblockGovernance.sol │ ├── RigoblockGovernance.sol │ ├── interfaces │ │ ├── IGovernanceStrategy.sol │ │ ├── IRigoblockGovernanceFactory.sol │ │ └── governance │ │ │ ├── IGovernanceEvents.sol │ │ │ ├── IGovernanceInitializer.sol │ │ │ ├── IGovernanceState.sol │ │ │ ├── IGovernanceUpgrade.sol │ │ │ └── IGovernanceVoting.sol │ ├── mixins │ │ ├── MixinAbstract.sol │ │ ├── MixinConstants.sol │ │ ├── MixinImmutables.sol │ │ ├── MixinInitializer.sol │ │ ├── MixinState.sol │ │ ├── MixinStorage.sol │ │ ├── MixinUpgrade.sol │ │ └── MixinVoting.sol │ ├── proxies │ │ ├── RigoblockGovernanceFactory.sol │ │ └── RigoblockGovernanceProxy.sol │ └── strategies │ │ └── RigoblockGovernanceStrategy.sol ├── protocol │ ├── IRigoblockV3Pool.sol │ ├── ISmartPool.sol │ ├── SmartPool.sol │ ├── core │ │ ├── actions │ │ │ ├── MixinActions.sol │ │ │ └── MixinOwnerActions.sol │ │ ├── immutable │ │ │ ├── MixinConstants.sol │ │ │ ├── MixinImmutables.sol │ │ │ └── MixinStorage.sol │ │ ├── state │ │ │ ├── MixinPoolState.sol │ │ │ ├── MixinPoolValue.sol │ │ │ └── MixinStorageAccessible.sol │ │ └── sys │ │ │ ├── MixinAbstract.sol │ │ │ ├── MixinFallback.sol │ │ │ └── MixinInitializer.sol │ ├── deps │ │ ├── Authority.sol │ │ ├── ExtensionsMap.sol │ │ ├── ExtensionsMapDeployer.sol │ │ ├── Kyc.sol │ │ └── PoolRegistry.sol │ ├── extensions │ │ ├── EApps.sol │ │ ├── EOracle.sol │ │ ├── EUpgrade.sol │ │ └── adapters │ │ │ ├── AGovernance.sol │ │ │ ├── AMulticall.sol │ │ │ ├── AStaking.sol │ │ │ ├── AUniswap.sol │ │ │ ├── AUniswapDecoder.sol │ │ │ ├── AUniswapRouter.sol │ │ │ └── interfaces │ │ │ ├── IAGovernance.sol │ │ │ ├── IAMulticall.sol │ │ │ ├── IAStaking.sol │ │ │ ├── IAUniswap.sol │ │ │ ├── IAUniswapRouter.sol │ │ │ ├── IEApps.sol │ │ │ ├── IEOracle.sol │ │ │ ├── IEUpgrade.sol │ │ │ ├── IMinimumVersion.sol │ │ │ └── IRigoblockExtensions.sol │ ├── interfaces │ │ ├── IAuthority.sol │ │ ├── IERC20.sol │ │ ├── IExtensionsMap.sol │ │ ├── IExtensionsMapDeployer.sol │ │ ├── IKyc.sol │ │ ├── IOracle.sol │ │ ├── IPoolRegistry.sol │ │ ├── IRigoblockPoolExtended.sol │ │ ├── IRigoblockPoolProxy.sol │ │ ├── IRigoblockPoolProxyFactory.sol │ │ ├── IWETH9.sol │ │ ├── pool │ │ │ ├── IRigoblockV3PoolActions.sol │ │ │ ├── IRigoblockV3PoolEvents.sol │ │ │ ├── IRigoblockV3PoolFallback.sol │ │ │ ├── IRigoblockV3PoolImmutable.sol │ │ │ ├── IRigoblockV3PoolInitializer.sol │ │ │ ├── IRigoblockV3PoolOwnerActions.sol │ │ │ ├── IRigoblockV3PoolState.sol │ │ │ └── IStorageAccessible.sol │ │ └── v4 │ │ │ └── pool │ │ │ ├── ISmartPoolActions.sol │ │ │ ├── ISmartPoolEvents.sol │ │ │ ├── ISmartPoolFallback.sol │ │ │ ├── ISmartPoolImmutable.sol │ │ │ ├── ISmartPoolInitializer.sol │ │ │ ├── ISmartPoolOwnerActions.sol │ │ │ ├── ISmartPoolState.sol │ │ │ └── IStorageAccessible.sol │ ├── libraries │ │ ├── ApplicationsLib.sol │ │ ├── EnumerableSet.sol │ │ ├── ReentrancyGuardTransient.sol │ │ ├── SafeTransferLib.sol │ │ ├── SlotDerivation.sol │ │ ├── StorageLib.sol │ │ ├── StorageSlot.sol │ │ ├── TransientSlot.sol │ │ ├── TransientStorage.sol │ │ └── VersionLib.sol │ ├── proxies │ │ ├── RigoblockPoolProxy.sol │ │ └── RigoblockPoolProxyFactory.sol │ └── types │ │ ├── Applications.sol │ │ ├── DeploymentParams.sol │ │ ├── ExternalApp.sol │ │ ├── NavComponents.sol │ │ └── Observation.sol ├── rigoToken │ ├── inflation │ │ ├── Inflation.sol │ │ └── InflationL2.sol │ ├── interfaces │ │ ├── IInflation.sol │ │ ├── IProofOfPerformance.sol │ │ └── IRigoToken.sol │ ├── proofOfPerformance │ │ └── ProofOfPerformance.sol │ └── rigoToken │ │ └── RigoToken.sol ├── staking │ ├── GrgVault.sol │ ├── Staking.sol │ ├── StakingProxy.sol │ ├── immutable │ │ ├── MixinConstants.sol │ │ ├── MixinDeploymentConstants.sol │ │ └── MixinStorage.sol │ ├── interfaces │ │ ├── IGrgVault.sol │ │ ├── IStaking.sol │ │ ├── IStakingEvents.sol │ │ ├── IStakingProxy.sol │ │ ├── IStorage.sol │ │ ├── IStorageInit.sol │ │ └── IStructs.sol │ ├── libs │ │ ├── LibCobbDouglas.sol │ │ ├── LibFixedMath.sol │ │ └── LibSafeDowncast.sol │ ├── rewards │ │ ├── MixinPopManager.sol │ │ └── MixinPopRewards.sol │ ├── stake │ │ ├── MixinStake.sol │ │ ├── MixinStakeBalances.sol │ │ └── MixinStakeStorage.sol │ ├── staking_pools │ │ ├── MixinCumulativeRewards.sol │ │ ├── MixinStakingPool.sol │ │ └── MixinStakingPoolRewards.sol │ └── sys │ │ ├── MixinAbstract.sol │ │ ├── MixinFinalizer.sol │ │ ├── MixinParams.sol │ │ └── MixinScheduler.sol ├── test │ ├── FlashGovernance.sol │ ├── MockOracle.sol │ ├── MockOwned.sol │ ├── MockPermit2.sol │ ├── MockStrategy.sol │ ├── MockUniUniversalRouter.sol │ ├── MockUniswapNpm.sol │ ├── MockUniswapPosm.sol │ ├── RogueStaking.sol │ ├── TestCobbDouglas.sol │ ├── TestLibFixedMath.sol │ ├── TestLibSafeDowncast.sol │ ├── TestReentrancyAttack.sol │ └── TestSafeTransferLib.sol ├── tokens │ ├── ERC20 │ │ ├── ERC20.sol │ │ └── IERC20.sol │ ├── UnlimitedAllowanceToken │ │ └── UnlimitedAllowanceToken.sol │ └── WETH9 │ │ └── WETH9.sol └── utils │ ├── 0xUtils │ ├── Authorizable.sol │ ├── ERC20Proxy │ │ ├── ERC20Proxy.sol │ │ ├── MAuthorizable.sol │ │ └── MixinAuthorizable.sol │ ├── IAssetData.sol │ ├── IAssetProxy.sol │ ├── IERC20Token.sol │ ├── IEtherToken.sol │ ├── LibFractions.sol │ ├── LibMath.sol │ ├── Ownable.sol │ └── interfaces │ │ ├── IAuthorizable.sol │ │ └── IOwnable.sol │ ├── exchanges │ └── uniswap │ │ ├── INonfungiblePositionManager │ │ └── INonfungiblePositionManager.sol │ │ └── v3-periphery │ │ └── contracts │ │ └── interfaces │ │ ├── IPeripheryImmutableState.sol │ │ ├── IPoolInitializer.sol │ │ └── external │ │ └── IERC721.sol │ ├── libSanitize │ └── LibSanitize.sol │ └── owned │ ├── IOwnedUninitialized.sol │ └── OwnedUninitialized.sol ├── foundry.toml ├── hardhat.config.ts ├── package.json ├── remappings.txt ├── src ├── deploy │ ├── deploy_extensions.ts │ ├── deploy_factories.ts │ ├── deploy_governance_tests.ts │ ├── deploy_rgbk_pool.ts │ ├── deploy_staking.ts │ ├── deploy_stakingL2.ts │ └── deploy_tests_setup.ts ├── index.ts ├── tasks │ ├── deploy_contracts.ts │ ├── local_verify.ts │ └── show_codesize.ts └── utils │ ├── constants.ts │ ├── proxies.ts │ └── solc.ts ├── test ├── core │ ├── RigoblockPool.Basetoken.spec.ts │ ├── RigoblockPool.Gascost.spec.ts │ ├── RigoblockPool.ReentrancyGuard.spec.ts │ ├── RigoblockPool.StorageAccessible.spec.ts │ └── RigoblockPool.spec.ts ├── deps │ ├── Authority.spec.ts │ ├── ExtensionsMap.spec.ts │ └── RigoblockPool.PoolRegistry.spec.ts ├── extensions │ ├── AGovernance.spec.ts │ ├── AMulticall.spec.ts │ ├── AStaking.spec.ts │ ├── AUniswap.spec.ts │ ├── AUniswapRouter.spec.ts │ └── EUpgrade.spec.ts ├── factory │ └── RigoblockPool.ProxyFactory.spec.ts ├── governance │ ├── Governance.Factory.spec.ts │ ├── Governance.Flash.spec.ts │ ├── Governance.Proxy.spec.ts │ ├── Governance.Upgrade.spec.ts │ └── Governance.spec.ts ├── inflation │ └── InflationL2.spec.ts ├── libraries │ └── TestSafeTransferLib.ts ├── shared │ ├── constants.ts │ ├── planner.ts │ └── v4Planner.ts ├── staking │ ├── Staking.spec.ts │ ├── StakingProxy.Inflation.spec.ts │ ├── StakingProxy.Pop.spec.ts │ ├── StakingProxy.RogueStaking.spec.ts │ ├── StakingProxy.Stake.spec.ts │ ├── StakingProxy.spec.ts │ └── libs │ │ ├── TestCobbDouglas.spec.ts │ │ ├── TestFixedMath.spec.ts │ │ └── TestSafeDowncast.spec.ts └── utils │ ├── eip712sig.ts │ ├── path.ts │ └── utils.ts ├── tsconfig.json ├── types └── solc.d.ts └── yarn.lock /.env.sample: -------------------------------------------------------------------------------- 1 | MNEMONIC="" 2 | # Used for infura based network 3 | INFURA_KEY="" 4 | # Used for custom network 5 | NODE_URL="" 6 | ETHERSCAN_API_KEY="" 7 | # Use the Safe singleton factory for singleton deployment. This is required if EIP-155 is enforce on a chain. 8 | # CUSTOM_DETERMINISTIC_DEPLOYMENT="true" 9 | PROD="" 10 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity 2 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | resolves #CHANGEME 2 | 3 | #### :notebook: Overview 4 | 5 | #### :warning: Dependencies (optional) 6 | Depends on #CHANGEME 7 | -------------------------------------------------------------------------------- /.github/autolabeler.yml: -------------------------------------------------------------------------------- 1 | contracts: ['contracts'] 2 | @rgbk/v3-contracts: ['packages/v3-contracts'] 3 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "npm" 4 | directory: "/" 5 | open-pull-requests-limit: 5 6 | schedule: 7 | interval: "daily" 8 | ignore: 9 | - dependency-name: "prettier-plugin-solidity" 10 | - dependency-name: "solhint" 11 | - package-ecosystem: "github-actions" 12 | directory: "/" 13 | schedule: 14 | interval: "weekly" 15 | open-pull-requests-limit: 5 16 | ignore: 17 | - dependency-name: "prettier-plugin-solidity" 18 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 30 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 30 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: stale 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: > 18 | This issue has been automatically closed because no activity occured in 30 days after being marked as stale. If it's still relevant - feel free to reopen. Thank you 19 | for your contributions. 20 | -------------------------------------------------------------------------------- /.github/workflows/check-pr-title.yml: -------------------------------------------------------------------------------- 1 | name: "Check PR Title" 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | - edited 8 | - synchronize 9 | 10 | jobs: 11 | check-pr-title: 12 | name: Check PR Title 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: amannn/action-semantic-pull-request@v5.5.3 16 | env: 17 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 18 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: v3-contracts 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - development 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | strategy: 14 | matrix: 15 | solidity: [""] 16 | settings: ['{"optimizer":{"enabled":true,"runs":200}}'] 17 | #include: 18 | #- solidity: "0.8.14" 19 | # settings: '{"optimizer":{"enabled":true,"runs":200}}' 20 | #- solidity: "0.7.4" 21 | # settings: '{"optimizer":{"enabled":true,"runs":200}}' 22 | #- solidity: "0.6.6" 23 | # settings: '{"optimizer":{"enabled":true,"runs":200}}' 24 | #- solidity: "0.5.0" 25 | # settings: '{"optimizer":{"enabled":true,"runs":200}}' 26 | env: 27 | SOLIDITY_VERSION: ${{ matrix.solidity }} 28 | SOLIDITY_SETTINGS: ${{ matrix.settings }} 29 | PROD: "" 30 | steps: 31 | - uses: actions/checkout@v4 32 | with: 33 | submodules: 'recursive' 34 | - uses: actions/setup-node@v4 35 | with: 36 | node-version: 22.12.0 37 | - uses: actions/cache@v4 38 | with: 39 | path: | 40 | **/node_modules 41 | **/.foundry 42 | key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} 43 | - name: Install Foundry 44 | uses: onbjerg/foundry-toolchain@v1 45 | with: 46 | version: nightly 47 | - run: yarn --frozen-lockfile 48 | - run: yarn build 49 | - run: yarn test 50 | - run: yarn coverage 51 | - name: Upload coverage to Codecov 52 | if: github.actor != 'dependabot[bot]' 53 | uses: codecov/codecov-action@v5 54 | with: 55 | token: ${{ secrets.CODECOV_TOKEN }} 56 | fail_ci_if_error: true 57 | verbose: true 58 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | strategy: 11 | matrix: 12 | solidity: [""] 13 | settings: ['{"optimizer":{"enabled":true,"runs":200}}'] 14 | env: 15 | SOLIDITY_VERSION: ${{ matrix.solidity }} 16 | SOLIDITY_SETTINGS: ${{ matrix.settings }} 17 | PROD: "" 18 | steps: 19 | - uses: actions/checkout@v4 20 | with: 21 | submodules: 'recursive' 22 | - uses: actions/setup-node@v4 23 | with: 24 | node-version: 22.12.0 25 | - uses: actions/cache@v4 26 | with: 27 | path: | 28 | "**/node_modules" 29 | **/.foundry 30 | key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} 31 | - name: Install Foundry 32 | uses: onbjerg/foundry-toolchain@v1 33 | with: 34 | version: nightly 35 | - run: yarn --frozen-lockfile 36 | - run: yarn build 37 | - run: yarn build:hardhat 38 | - run: yarn test 39 | 40 | publish-npm: 41 | needs: build 42 | runs-on: ubuntu-latest 43 | # The following strategy and env are used by hardhat compile 44 | strategy: 45 | matrix: 46 | solidity: [""] 47 | settings: ['{"optimizer":{"enabled":true,"runs":200}}'] 48 | env: 49 | SOLIDITY_VERSION: ${{ matrix.solidity }} 50 | SOLIDITY_SETTINGS: ${{ matrix.settings }} 51 | steps: 52 | - uses: actions/checkout@v4 53 | - uses: actions/setup-node@v4 54 | with: 55 | node-version: 22.12.0 56 | registry-url: https://registry.npmjs.org/ 57 | always-auth: true 58 | - name: Install Foundry 59 | uses: onbjerg/foundry-toolchain@v1 60 | with: 61 | version: nightly 62 | - uses: actions/cache@v4 63 | with: 64 | path: "**/node_modules" 65 | key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} 66 | - run: yarn --frozen-lockfile 67 | - run: yarn publish 68 | env: 69 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} 70 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | cache_forge/ 3 | failing_metadata/ 4 | out/ 5 | node_modules/ 6 | .DS_Store 7 | .zos.session 8 | .openzeppelin/.session 9 | deployments/ 10 | env/ 11 | dist/ 12 | .env 13 | bin/ 14 | solc 15 | coverage/ 16 | coverage.json 17 | yarn-error.log 18 | 19 | #generated contract artifacts 20 | *artifacts/ 21 | contracts/**/**/*.json 22 | contracts/**/**/**/*.json 23 | 24 | #contracts deps 25 | contracts/.deps/ 26 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | 2 | [submodule "lib/solmate"] 3 | path = lib/solmate 4 | url = https://github.com/transmissions11/solmate.git 5 | [submodule "lib/permit2"] 6 | path = lib/permit2 7 | url = https://github.com/Uniswap/permit2.git 8 | [submodule "lib/forge-std"] 9 | path = lib/forge-std 10 | url = https://github.com/foundry-rs/forge-std 11 | [submodule "lib/universal-router"] 12 | path = lib/universal-router 13 | url = https://github.com/Uniswap/universal-router.git 14 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | # Redirect output to stderr. 5 | exec 1>&2 6 | 7 | # prevent it.only or describe.only commited 8 | if [ "$allowonlytests" != "true" ] && 9 | test $(git diff --cached | grep -E "\b(it|describe).only\(" | wc -l) != 0 10 | then 11 | cat <<\EOF 12 | Error: Attempt to add it.only or describe.only - which may disable all other tests 13 | 14 | If you know what you are doing you can disable this check using: 15 | 16 | git config hooks.allowonlytests true 17 | EOF 18 | exit 1 19 | fi 20 | 21 | exit 0 22 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v22.12.0 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "overrides": [ 3 | { 4 | "files": "*.sol", 5 | "options": { 6 | "printWidth": 120, 7 | "tabWidth": 4, 8 | "useTabs": false, 9 | "singleQuote": false, 10 | "bracketSpacing": false, 11 | "explicitTypes": "always" 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | skipFiles: [ 3 | './examples', 4 | './tokens', 5 | './utils', 6 | './protocol/libraries/SlotDerivation.sol', 7 | './protocol/libraries/ReentrancyGuardTransient.sol', 8 | './protocol/libraries/TransientSlot.sol' 9 | ], 10 | mocha: { 11 | grep: "@skip-on-coverage", // Find everything with this tag 12 | invert: true // Run the grep's inverse set. 13 | }, 14 | configureYulOptimizer: true, 15 | viaIR: true, 16 | details: { 17 | yulDetails: { 18 | optimizerSteps:"u", 19 | }, 20 | }, 21 | solcOptimizerDetails: { 22 | peephole: false, 23 | jumpdestRemover: false, 24 | orderLiterals: true, 25 | deduplicate: false, 26 | cse: false, 27 | constantOptimizer: false, 28 | yul: true 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:recommended", 3 | "plugins": [ 4 | "prettier" 5 | ], 6 | "rules": { 7 | "compiler-version": "off", 8 | "func-visibility": [ 9 | "warn", 10 | { 11 | "ignoreConstructors": true 12 | } 13 | ], 14 | "prettier/prettier": "error", 15 | "not-rely-on-time": "off", 16 | "reason-string": "off", 17 | "no-empty-blocks": "off", 18 | "avoid-low-level-calls": "off", 19 | "no-inline-assembly": "off", 20 | "var-name-mixedcase": "off", 21 | "func-name-mixedcase": "off" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [2.0.6](https://github.com/rigoblock/v3-contracts/compare/v2.0.5...v2.0.6) (2025-05-29) 2 | 3 | 4 | ### Bug Fixes 5 | 6 | * base token price feed assertion also on first mint ([bf5344b](https://github.com/rigoblock/v3-contracts/commit/bf5344b73da92865b31e076f856acc347c4623ce)) 7 | 8 | 9 | 10 | ## [2.0.5](https://github.com/rigoblock/v3-contracts/compare/v2.0.4...v2.0.5) (2025-05-25) 11 | 12 | 13 | ### Bug Fixes 14 | 15 | * hardhat compile setup in npm publish task ([c79412c](https://github.com/rigoblock/v3-contracts/commit/c79412cbfcee69a5437184d2cec29f5eb5b5e82b)) 16 | 17 | 18 | 19 | ## [2.0.4](https://github.com/rigoblock/v3-contracts/compare/v2.0.3...v2.0.4) (2025-05-25) 20 | 21 | 22 | ### Bug Fixes 23 | 24 | * release script ([d552594](https://github.com/rigoblock/v3-contracts/commit/d5525946c949cfa463417a312c121ca1624ecd0f)) 25 | 26 | 27 | 28 | ## [2.0.3](https://github.com/rigoblock/v3-contracts/compare/v2.0.2...v2.0.3) (2025-05-25) 29 | 30 | 31 | ### Bug Fixes 32 | 33 | * attach value with uni v4 exact out swap ([4b0b480](https://github.com/rigoblock/v3-contracts/commit/4b0b480aed904f71e51e69784e949b90e6eff2d0)) 34 | * remove swap-router-contracts package ([959d630](https://github.com/rigoblock/v3-contracts/commit/959d630cf617f8e21f651ff92a667ab60a3e5bbb)) 35 | * staking proxy address constant ([3167b46](https://github.com/rigoblock/v3-contracts/commit/3167b46c7135d90dc434d3c98ad7146df4ba9fad)) 36 | 37 | 38 | 39 | ## [2.0.2](https://github.com/rigoblock/v3-contracts/compare/v2.0.1...v2.0.2) (2025-05-11) 40 | 41 | 42 | ### Bug Fixes 43 | 44 | * extensions map salt ([be60fd4](https://github.com/rigoblock/v3-contracts/commit/be60fd45e2c9401e34da71a2ebcb45c3f10717a2)) 45 | * remove unused input param ([e53780d](https://github.com/rigoblock/v3-contracts/commit/e53780da1cf0961181110c14a33269b548a1bb0a)) 46 | * unichain wrap/unwrap ([7cc7504](https://github.com/rigoblock/v3-contracts/commit/7cc7504f527cf9032f92b6c2bb6c473625fd9979)) 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # v3-contracts 2 | Smart contracts of RigoBlock v3 3 | ===================== 4 | 5 | [![npm version](https://badge.fury.io/js/@rgbk%2Fv3-contracts.svg)](https://badge.fury.io/js/@rgbk%2Fv3-contracts) 6 | [![Build Status](https://github.com/rigoblock/v3-contracts/workflows/v3-contracts/badge.svg?branch=development)](https://github.com/rigoblock/v3-contracts/actions) 7 | [![Codecov Status](https://codecov.io/gh/RigoBlock/v3-contracts/graph/badge.svg?token=6W6HWC1DZP)](https://codecov.io/gh/RigoBlock/v3-contracts) 8 | 9 | 10 | Usage 11 | ----- 12 | ### Install requirements with yarn: 13 | 14 | ```bash 15 | yarn 16 | ``` 17 | 18 | ### Run all tests: 19 | 20 | ```bash 21 | yarn build 22 | yarn test 23 | ``` 24 | 25 | ### storage upgrades 26 | New storage variables in the implementation must be added to a dedicated storage to prevent storage collision. 27 | 28 | ### Commit format: 29 | PR must follow "Conventional Commits spec". PR title is checked upon opening. Examples for valid PR titles: 30 | 31 | - ```fix:``` Correct typo. (patch) 32 | - ```feat:``` Add support for ... (minor) 33 | - ```feat!:``` Drop support for ... (major) 34 | 35 | Other PR titles are also valid: 36 | 37 | - ```build:```,```chore:```,```ci:```,```docs:```,```style:```,```refactor:```,```perf:```,```test:``` 38 | 39 | ### License 40 | All smart contracts are released under Apache-2.0 41 | -------------------------------------------------------------------------------- /contracts/governance/IRigoblockGovernance.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | /* 3 | 4 | Copyright 2023 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import "./interfaces/governance/IGovernanceEvents.sol"; 23 | import "./interfaces/governance/IGovernanceInitializer.sol"; 24 | import "./interfaces/governance/IGovernanceState.sol"; 25 | import "./interfaces/governance/IGovernanceUpgrade.sol"; 26 | import "./interfaces/governance/IGovernanceVoting.sol"; 27 | 28 | interface IRigoblockGovernance is 29 | IGovernanceEvents, 30 | IGovernanceInitializer, 31 | IGovernanceUpgrade, 32 | IGovernanceVoting, 33 | IGovernanceState 34 | {} 35 | -------------------------------------------------------------------------------- /contracts/governance/RigoblockGovernance.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | /* 3 | 4 | Copyright 2023 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity 0.8.17; 21 | 22 | import "./mixins/MixinInitializer.sol"; 23 | import "./mixins/MixinState.sol"; 24 | import "./mixins/MixinStorage.sol"; 25 | import "./mixins/MixinUpgrade.sol"; 26 | import "./mixins/MixinVoting.sol"; 27 | import "./IRigoblockGovernance.sol"; 28 | 29 | contract RigoblockGovernance is 30 | IRigoblockGovernance, 31 | MixinStorage, 32 | MixinInitializer, 33 | MixinUpgrade, 34 | MixinVoting, 35 | MixinState 36 | { 37 | /// @notice Constructor has no inputs to guarantee same deterministic address across chains. 38 | /// @dev Setting high proposal threshold locks propose action, which also lock vote actions. 39 | constructor() MixinImmutables() MixinStorage() { 40 | _paramsWrapper().governanceParameters = GovernanceParameters({ 41 | strategy: address(0), 42 | proposalThreshold: type(uint256).max, 43 | quorumThreshold: 0, 44 | timeType: TimeType.Timestamp 45 | }); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /contracts/governance/interfaces/IGovernanceStrategy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2023 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import "../IRigoblockGovernance.sol"; 23 | import "./IRigoblockGovernanceFactory.sol"; 24 | 25 | interface IGovernanceStrategy { 26 | /// @notice Reverts if initialization paramters are incorrect. 27 | /// @dev Only used at initialization, as params deleted from factory storage after setup. 28 | /// @param params Tuple of factory parameters. 29 | function assertValidInitParams(IRigoblockGovernanceFactory.Parameters calldata params) external view; 30 | 31 | /// @notice Reverts if thresholds are incorrect. 32 | /// @param proposalThreshold Number of votes required to make a proposal. 33 | /// @param quorumThreshold Number of votes required for a proposal to succeed. 34 | function assertValidThresholds(uint256 proposalThreshold, uint256 quorumThreshold) external view; 35 | 36 | /// @notice Returns the state of a proposal for a required quorum. 37 | /// @param proposal Tuple of the proposal. 38 | /// @param minimumQuorum Number of votes required for a proposal to pass. 39 | /// @return Tuple of the proposal state. 40 | function getProposalState(IRigoblockGovernance.Proposal calldata proposal, uint256 minimumQuorum) 41 | external 42 | view 43 | returns (IRigoblockGovernance.ProposalState); 44 | 45 | /// @notice Return the voting period. 46 | /// @return Number of seconds of period duration. 47 | function votingPeriod() external view returns (uint256); 48 | 49 | /// @notice Returns the voting timestamps. 50 | /// @return startBlockOrTime Timestamp when proposal starts. 51 | /// @return endBlockOrTime Timestamp when voting ends. 52 | function votingTimestamps() external view returns (uint256 startBlockOrTime, uint256 endBlockOrTime); 53 | 54 | /// @notice Return a user's voting power. 55 | /// @param account Address to check votes for. 56 | function getVotingPower(address account) external view returns (uint256); 57 | } 58 | -------------------------------------------------------------------------------- /contracts/governance/interfaces/IRigoblockGovernanceFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0-or-later 2 | /* 3 | 4 | Copyright 2017-2022 RigoBlock, Rigo Investment Sagl, Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import "../IRigoblockGovernance.sol"; 23 | 24 | // solhint-disable-next-line 25 | interface IRigoblockGovernanceFactory { 26 | /// @notice Emitted when a governance is created. 27 | /// @param governance Address of the governance proxy. 28 | event GovernanceCreated(address governance); 29 | 30 | /// @notice Creates a new governance proxy. 31 | /// @param implementation Address of the governance implementation contract. 32 | /// @param governanceStrategy Address of the voting strategy. 33 | /// @param proposalThreshold Number of votes required for creating a new proposal. 34 | /// @param quorumThreshold Number of votes required for execution. 35 | /// @param timeType Enum of time type (block number or timestamp). 36 | /// @param name Human readable string of the name. 37 | /// @return governance Address of the new governance. 38 | function createGovernance( 39 | address implementation, 40 | address governanceStrategy, 41 | uint256 proposalThreshold, 42 | uint256 quorumThreshold, 43 | IRigoblockGovernance.TimeType timeType, 44 | string calldata name 45 | ) external returns (address governance); 46 | 47 | struct Parameters { 48 | /// @notice Address of the governance implementation contract. 49 | address implementation; 50 | /// @notice Address of the voting strategy. 51 | address governanceStrategy; 52 | /// @notice Number of votes required for creating a new proposal. 53 | uint256 proposalThreshold; 54 | /// @notice Number of votes required for execution. 55 | uint256 quorumThreshold; 56 | /// @notice Type of time chosed, block number of timestamp. 57 | IRigoblockGovernance.TimeType timeType; 58 | /// @notice String of the name of the application. 59 | string name; 60 | } 61 | 62 | /// @notice Returns the governance initialization parameters at proxy deploy. 63 | /// @return Tuple of the governance parameters. 64 | function parameters() external view returns (Parameters memory); 65 | } 66 | -------------------------------------------------------------------------------- /contracts/governance/interfaces/governance/IGovernanceEvents.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | /* 3 | 4 | Copyright 2023 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import "./IGovernanceVoting.sol"; 23 | 24 | interface IGovernanceEvents { 25 | /// @notice Emitted when a new proposal is created. 26 | /// @param proposer Address of the proposer. 27 | /// @param proposalId Number of the proposal. 28 | /// @param actions Struct array of actions (targets, datas, values). 29 | /// @param startBlockOrTime Timestamp in seconds after which proposal can be voted on. 30 | /// @param endBlockOrTime Timestamp in seconds after which proposal can be executed. 31 | /// @param description String description of proposal. 32 | event ProposalCreated( 33 | address proposer, 34 | uint256 proposalId, 35 | IGovernanceVoting.ProposedAction[] actions, 36 | uint256 startBlockOrTime, 37 | uint256 endBlockOrTime, 38 | string description 39 | ); 40 | 41 | /// @notice Emitted when a proposal is executed. 42 | /// @param proposalId Number of the proposal. 43 | event ProposalExecuted(uint256 proposalId); 44 | 45 | /// @notice Emmited when the governance strategy is upgraded. 46 | /// @param newStrategy Address of the new strategy contract. 47 | event StrategyUpgraded(address newStrategy); 48 | 49 | /// @notice Emitted when voting thresholds get updated. 50 | /// @dev Only governance can update thresholds. 51 | /// @param proposalThreshold Number of votes required to add a proposal. 52 | /// @param quorumThreshold Number of votes required to execute a proposal. 53 | event ThresholdsUpdated(uint256 proposalThreshold, uint256 quorumThreshold); 54 | 55 | /// @notice Emitted when implementation written to proxy storage. 56 | /// @dev Emitted also at first variable initialization. 57 | /// @param newImplementation Address of the new implementation. 58 | event Upgraded(address indexed newImplementation); 59 | 60 | /// @notice Emitted when a voter votes. 61 | /// @param voter Address of the voter. 62 | /// @param proposalId Number of the proposal. 63 | /// @param voteType Number of vote type. 64 | /// @param votingPower Number of votes. 65 | event VoteCast(address voter, uint256 proposalId, IGovernanceVoting.VoteType voteType, uint256 votingPower); 66 | } 67 | -------------------------------------------------------------------------------- /contracts/governance/interfaces/governance/IGovernanceInitializer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | /* 3 | 4 | Copyright 2023 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | interface IGovernanceInitializer { 23 | /// @notice Initializes the Rigoblock Governance. 24 | /// @dev Params are stored in factory and read from there. 25 | function initializeGovernance() external; 26 | } 27 | -------------------------------------------------------------------------------- /contracts/governance/interfaces/governance/IGovernanceUpgrade.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | /* 3 | 4 | Copyright 2023 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | interface IGovernanceUpgrade { 23 | /// @notice Updates the proposal and quorum thresholds to the given values. 24 | /// @dev Only callable by the governance contract itself. 25 | /// @dev Thresholds can only be updated via a successful governance proposal. 26 | /// @param newProposalThreshold The new value for the proposal threshold. 27 | /// @param newQuorumThreshold The new value for the quorum threshold. 28 | function updateThresholds(uint256 newProposalThreshold, uint256 newQuorumThreshold) external; 29 | 30 | /// @notice Updates the governance implementation address. 31 | /// @dev Only callable after successful voting. 32 | /// @param newImplementation Address of the new governance implementation contract. 33 | function upgradeImplementation(address newImplementation) external; 34 | 35 | /// @notice Updates the governance strategy plugin. 36 | /// @dev Only callable by the governance contract itself. 37 | /// @param newStrategy Address of the new strategy contract. 38 | function upgradeStrategy(address newStrategy) external; 39 | } 40 | -------------------------------------------------------------------------------- /contracts/governance/interfaces/governance/IGovernanceVoting.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | /* 3 | 4 | Copyright 2023 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import "./IGovernanceEvents.sol"; 23 | 24 | interface IGovernanceVoting { 25 | enum VoteType { 26 | For, 27 | Against, 28 | Abstain 29 | } 30 | 31 | /// @notice Casts a vote for the given proposal. 32 | /// @dev Only callable during the voting period for that proposal. One address can only vote once. 33 | /// @param proposalId The ID of the proposal to vote on. 34 | /// @param voteType Whether to support, not support or abstain. 35 | function castVote(uint256 proposalId, VoteType voteType) external; 36 | 37 | /// @notice Casts a vote for the given proposal, by signature. 38 | /// @dev Only callable during the voting period for that proposal. One voter can only vote once. 39 | /// @param proposalId The ID of the proposal to vote on. 40 | /// @param voteType Whether to support, not support or abstain. 41 | /// @param v the v field of the signature. 42 | /// @param r the r field of the signature. 43 | /// @param s the s field of the signature. 44 | function castVoteBySignature( 45 | uint256 proposalId, 46 | VoteType voteType, 47 | uint8 v, 48 | bytes32 r, 49 | bytes32 s 50 | ) external; 51 | 52 | /// @notice Executes a proposal that has passed and is currently executable. 53 | /// @param proposalId The ID of the proposal to execute. 54 | function execute(uint256 proposalId) external payable; 55 | 56 | struct ProposedAction { 57 | address target; 58 | bytes data; 59 | uint256 value; 60 | } 61 | 62 | /// @notice Creates a proposal on the the given actions. Must have at least `proposalThreshold`. 63 | /// @dev Must have at least `proposalThreshold` of voting power to call this function. 64 | /// @param actions The proposed actions. An action specifies a contract call. 65 | /// @param description A text description for the proposal. 66 | /// @return proposalId The ID of the newly created proposal. 67 | function propose(ProposedAction[] calldata actions, string calldata description) 68 | external 69 | returns (uint256 proposalId); 70 | } 71 | -------------------------------------------------------------------------------- /contracts/governance/mixins/MixinAbstract.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2023 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import "../IRigoblockGovernance.sol"; 23 | 24 | abstract contract MixinAbstract { 25 | function _getProposalCount() internal view virtual returns (uint256); 26 | 27 | function _getProposalState(uint256 proposalId) internal view virtual returns (IRigoblockGovernance.ProposalState); 28 | 29 | function _getVotingPower(address account) internal view virtual returns (uint256); 30 | } 31 | -------------------------------------------------------------------------------- /contracts/governance/mixins/MixinConstants.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2023 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import "../IRigoblockGovernance.sol"; 23 | 24 | /// @notice Constants are copied in the bytecode and not assigned a storage slot, can safely be added to this contract. 25 | abstract contract MixinConstants is IRigoblockGovernance { 26 | /// @notice Contract version 27 | string internal constant VERSION = "1.0.0"; 28 | 29 | /// @notice Maximum operations per proposal 30 | uint256 internal constant PROPOSAL_MAX_OPERATIONS = 10; 31 | 32 | /// @notice The EIP-712 typehash for the contract's domain 33 | bytes32 internal constant DOMAIN_TYPEHASH = 34 | keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); 35 | 36 | /// @notice The EIP-712 typehash for the vote struct 37 | bytes32 internal constant VOTE_TYPEHASH = keccak256("Vote(uint256 proposalId,uint8 voteType)"); 38 | 39 | bytes32 internal constant _GOVERNANCE_PARAMS_SLOT = 40 | 0x0116feaee435dceaf94f40403a5223724fba6d709cb4ce4aea5becab48feb141; 41 | 42 | // implementation slot is same as declared in proxy 43 | bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; 44 | 45 | bytes32 internal constant _NAME_SLOT = 0x553222b140782d4f4112160b374e6b1dc38e2837c7dcbf3ef473031724ed3bd4; 46 | 47 | bytes32 internal constant _PROPOSAL_SLOT = 0x52dbe777b6bf9bbaf43befe2c8e8af61027e6a0a8901def318a34b207514b5bc; 48 | 49 | bytes32 internal constant _PROPOSAL_COUNT_SLOT = 0x7d19d505a441201fb38442238c5f65c45e6231c74b35aed1c92ad842019eab9f; 50 | 51 | bytes32 internal constant _PROPOSED_ACTION_SLOT = 52 | 0xe4ff3d203d0a873fb9ffd3a1bbd07943574a73114c5affe6aa0217c743adeb06; 53 | 54 | bytes32 internal constant _RECEIPT_SLOT = 0x5a7421539532aa5504e4251551519aa0a06f7c2a3b40bbade5235843e09ad5fe; 55 | } 56 | -------------------------------------------------------------------------------- /contracts/governance/mixins/MixinImmutables.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2023 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import "./MixinConstants.sol"; 23 | 24 | /// @notice Immutables are copied in the bytecode and not assigned a storage slot 25 | /// @dev New immutables can safely be added to this contract without ordering. 26 | abstract contract MixinImmutables is MixinConstants { 27 | constructor() {} 28 | } 29 | -------------------------------------------------------------------------------- /contracts/governance/mixins/MixinInitializer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2023 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import "../interfaces/IGovernanceStrategy.sol"; 23 | import "../interfaces/IRigoblockGovernanceFactory.sol"; 24 | import "./MixinStorage.sol"; 25 | 26 | abstract contract MixinInitializer is MixinStorage { 27 | error InitParamsVerification(); 28 | 29 | modifier onlyUninitialized() { 30 | // proxy is always initialized in the constructor, therefore 31 | // empty extcodesize means the governance has not been initialized 32 | require(address(this).code.length == 0, "ALREADY_INITIALIZED_ERROR"); 33 | _; 34 | } 35 | 36 | /// @inheritdoc IGovernanceInitializer 37 | function initializeGovernance() external override onlyUninitialized { 38 | IRigoblockGovernanceFactory.Parameters memory params = IRigoblockGovernanceFactory(msg.sender).parameters(); 39 | 40 | // we require the strategy contract to implement method assertValidInitParams and are not interested in the returned error. 41 | try IGovernanceStrategy(params.governanceStrategy).assertValidInitParams(params) {} catch { 42 | revert InitParamsVerification(); 43 | } 44 | 45 | _name().value = params.name; 46 | _paramsWrapper().governanceParameters = GovernanceParameters({ 47 | strategy: params.governanceStrategy, 48 | proposalThreshold: params.proposalThreshold, 49 | quorumThreshold: params.quorumThreshold, 50 | timeType: params.timeType 51 | }); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /contracts/governance/proxies/RigoblockGovernanceFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0-or-later 2 | /* 3 | 4 | Copyright 2023 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity 0.8.17; 21 | 22 | import "./RigoblockGovernanceProxy.sol"; 23 | import "../IRigoblockGovernance.sol"; 24 | import "../interfaces/IRigoblockGovernanceFactory.sol"; 25 | 26 | // solhint-disable-next-line 27 | contract RigoblockGovernanceFactory is IRigoblockGovernanceFactory { 28 | Parameters private _parameters; 29 | 30 | // @inheritdoc IRigoblockGovernanceFactory 31 | function createGovernance( 32 | address implementation, 33 | address governanceStrategy, 34 | uint256 proposalThreshold, 35 | uint256 quorumThreshold, 36 | IRigoblockGovernance.TimeType timeType, 37 | string calldata name 38 | ) external returns (address governance) { 39 | assert(_isContract(implementation)); 40 | assert(_isContract(governanceStrategy)); 41 | 42 | // we write to storage to allow proxy to read initialization parameters 43 | _parameters = Parameters({ 44 | implementation: implementation, 45 | governanceStrategy: governanceStrategy, 46 | proposalThreshold: proposalThreshold, 47 | quorumThreshold: quorumThreshold, 48 | timeType: timeType, 49 | name: name 50 | }); 51 | governance = address(new RigoblockGovernanceProxy{salt: keccak256(abi.encode(msg.sender, name))}()); 52 | 53 | delete _parameters; 54 | emit GovernanceCreated(governance); 55 | } 56 | 57 | // @inheritdoc IRigoblockGovernanceFactory 58 | function parameters() external view override returns (Parameters memory) { 59 | return _parameters; 60 | } 61 | 62 | /// @dev Returns whether an address is a contract. 63 | /// @return Bool target address has code. 64 | function _isContract(address target) private view returns (bool) { 65 | return target.code.length > 0; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /contracts/protocol/IRigoblockV3Pool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2022 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import "./interfaces/IERC20.sol"; 23 | import "./interfaces/pool/IRigoblockV3PoolActions.sol"; 24 | import "./interfaces/pool/IRigoblockV3PoolEvents.sol"; 25 | import "./interfaces/pool/IRigoblockV3PoolFallback.sol"; 26 | import "./interfaces/pool/IRigoblockV3PoolImmutable.sol"; 27 | import "./interfaces/pool/IRigoblockV3PoolInitializer.sol"; 28 | import "./interfaces/pool/IRigoblockV3PoolOwnerActions.sol"; 29 | import "./interfaces/pool/IRigoblockV3PoolState.sol"; 30 | import "./interfaces/pool/IStorageAccessible.sol"; 31 | 32 | /// @title Rigoblock V3 Pool Interface - Allows interaction with the pool contract. 33 | /// @author Gabriele Rigo - 34 | // solhint-disable-next-line 35 | interface IRigoblockV3Pool is 36 | IERC20, 37 | IRigoblockV3PoolImmutable, 38 | IRigoblockV3PoolEvents, 39 | IRigoblockV3PoolFallback, 40 | IRigoblockV3PoolInitializer, 41 | IRigoblockV3PoolActions, 42 | IRigoblockV3PoolOwnerActions, 43 | IRigoblockV3PoolState, 44 | IStorageAccessible 45 | { 46 | 47 | } 48 | -------------------------------------------------------------------------------- /contracts/protocol/ISmartPool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2025 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import {IERC20} from "./interfaces/IERC20.sol"; 23 | import {ISmartPoolActions} from "./interfaces/v4/pool/ISmartPoolActions.sol"; 24 | import {ISmartPoolEvents} from "./interfaces/v4/pool/ISmartPoolEvents.sol"; 25 | import {ISmartPoolFallback} from "./interfaces/v4/pool/ISmartPoolFallback.sol"; 26 | import {ISmartPoolImmutable} from "./interfaces/v4/pool/ISmartPoolImmutable.sol"; 27 | import {ISmartPoolInitializer} from "./interfaces/v4/pool/ISmartPoolInitializer.sol"; 28 | import {ISmartPoolOwnerActions} from "./interfaces/v4/pool/ISmartPoolOwnerActions.sol"; 29 | import {ISmartPoolState} from "./interfaces/v4/pool/ISmartPoolState.sol"; 30 | import {IStorageAccessible} from "./interfaces/v4/pool/IStorageAccessible.sol"; 31 | 32 | /// @title Rigoblock V3 Pool Interface - Allows interaction with the pool contract. 33 | /// @author Gabriele Rigo - 34 | // solhint-disable-next-line 35 | interface ISmartPool is 36 | IERC20, 37 | ISmartPoolImmutable, 38 | ISmartPoolEvents, 39 | ISmartPoolFallback, 40 | ISmartPoolInitializer, 41 | ISmartPoolActions, 42 | ISmartPoolOwnerActions, 43 | ISmartPoolState, 44 | IStorageAccessible 45 | {} 46 | -------------------------------------------------------------------------------- /contracts/protocol/SmartPool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2022-2025 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity 0.8.28; 21 | 22 | import {ISmartPool} from "./ISmartPool.sol"; 23 | import {MixinImmutables} from "./core/immutable/MixinImmutables.sol"; 24 | import {MixinStorage} from "./core/immutable/MixinStorage.sol"; 25 | import {MixinPoolState} from "./core/state/MixinPoolState.sol"; 26 | import {MixinStorageAccessible} from "./core/state/MixinStorageAccessible.sol"; 27 | import {MixinAbstract} from "./core/sys/MixinAbstract.sol"; 28 | import {MixinInitializer} from "./core/sys/MixinInitializer.sol"; 29 | import {MixinFallback} from "./core/sys/MixinFallback.sol"; 30 | 31 | /// @title ISmartPool - A set of rules for Rigoblock pools. 32 | /// @author Gabriele Rigo - 33 | // solhint-disable-next-line 34 | contract SmartPool is 35 | ISmartPool, 36 | MixinStorage, 37 | MixinFallback, 38 | MixinInitializer, 39 | MixinAbstract, 40 | MixinPoolState, 41 | MixinStorageAccessible 42 | { 43 | /// @notice Owner is initialized to 0 to lock owner actions in this implementation. 44 | /// @notice Kyc provider set as will effectively lock direct mint/burn actions. 45 | /// @notice ExtensionsMap validation is performed in MixinImmutables constructor. 46 | constructor(address authority, address extensionsMap) MixinImmutables(authority, extensionsMap) { 47 | // we lock implementation at deploy 48 | pool().owner = _ZERO_ADDRESS; 49 | poolParams().kycProvider == _BASE_TOKEN_FLAG; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /contracts/protocol/core/immutable/MixinConstants.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2022-2025 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import {ISmartPool} from "../../ISmartPool.sol"; 23 | import {ISmartPoolImmutable} from "../../interfaces/v4/pool/ISmartPoolImmutable.sol"; 24 | 25 | /// @notice Constants are copied in the bytecode and not assigned a storage slot, can safely be added to this contract. 26 | /// @dev Inheriting from interface is required as we override public variables. 27 | abstract contract MixinConstants is ISmartPool { 28 | /// @inheritdoc ISmartPoolImmutable 29 | string public constant override VERSION = "4.0.2"; 30 | 31 | bytes32 internal constant _APPLICATIONS_SLOT = 0xdc487a67cca3fd0341a90d1b8834103014d2a61e6a212e57883f8680b8f9c831; 32 | 33 | bytes32 internal constant _POOL_INIT_SLOT = 0xe48b9bb119adfc3bccddcc581484cc6725fe8d292ebfcec7d67b1f93138d8bd8; 34 | 35 | bytes32 internal constant _POOL_VARIABLES_SLOT = 0xe3ed9e7d534645c345f2d15f0c405f8de0227b60eb37bbeb25b26db462415dec; 36 | 37 | bytes32 internal constant _POOL_TOKENS_SLOT = 0xf46fb7ff9ff9a406787c810524417c818e45ab2f1997f38c2555c845d23bb9f6; 38 | 39 | bytes32 internal constant _POOL_ACCOUNTS_SLOT = 0xfd7547127f88410746fb7969b9adb4f9e9d8d2436aa2d2277b1103542deb7b8e; 40 | 41 | bytes32 internal constant _TOKEN_REGISTRY_SLOT = 0x3dcde6752c7421366e48f002bbf8d6493462e0e43af349bebb99f0470a12300d; 42 | 43 | address internal constant _ZERO_ADDRESS = address(0); 44 | 45 | address internal constant _BASE_TOKEN_FLAG = address(1); 46 | 47 | uint16 internal constant _FEE_BASE = 10000; 48 | 49 | uint16 internal constant _MAX_SPREAD = 500; // +-5%, in basis points 50 | 51 | uint16 internal constant _MAX_TRANSACTION_FEE = 100; // maximum 1% 52 | 53 | // minimum order size 1/1000th of base to avoid dust clogging things up 54 | uint16 internal constant _MINIMUM_ORDER_DIVISOR = 1e3; 55 | 56 | uint16 internal constant _SPREAD_BASE = 10000; 57 | 58 | uint48 internal constant _MAX_LOCKUP = 30 days; 59 | 60 | uint48 internal constant _MIN_LOCKUP = 1 days; 61 | } 62 | -------------------------------------------------------------------------------- /contracts/protocol/core/immutable/MixinImmutables.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2022-2025 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import {MixinConstants} from "./MixinConstants.sol"; 23 | import {ISmartPoolImmutable} from "../../interfaces/v4/pool/ISmartPoolImmutable.sol"; 24 | import {IExtensionsMap} from "../../interfaces/IExtensionsMap.sol"; 25 | 26 | /// @notice Immutables are not assigned a storage slot, can be safely added to this contract. 27 | abstract contract MixinImmutables is MixinConstants { 28 | error InvalidAuthorityInput(); 29 | error InvalidExtensionsMapInput(); 30 | 31 | /// @inheritdoc ISmartPoolImmutable 32 | address public immutable override authority; 33 | 34 | ///@inheritdoc ISmartPoolImmutable 35 | address public immutable override wrappedNative; 36 | 37 | // EIP1967 standard, must be immutable to be compile-time constant. 38 | address internal immutable _implementation; 39 | 40 | IExtensionsMap internal immutable _extensionsMap; 41 | 42 | /// @notice The ExtensionsMap interface is required to implement the expected methods as sanity check. 43 | constructor(address _authority, address extensionsMap) { 44 | require(_authority.code.length > 0, InvalidAuthorityInput()); 45 | require(extensionsMap.code.length > 0, InvalidExtensionsMapInput()); 46 | authority = _authority; 47 | 48 | _implementation = address(this); 49 | 50 | // initialize extensions mapping and assert it implements `getExtensionBySelector` method 51 | _extensionsMap = IExtensionsMap(extensionsMap); 52 | wrappedNative = _extensionsMap.wrappedNative(); 53 | 54 | // the following assertion will alway be true, as long as IExtensionsMap implements the expected methods. 55 | assert( 56 | IExtensionsMap.eApps.selector ^ 57 | IExtensionsMap.eOracle.selector ^ 58 | IExtensionsMap.eUpgrade.selector ^ 59 | IExtensionsMap.wrappedNative.selector ^ 60 | IExtensionsMap.getExtensionBySelector.selector == 61 | type(IExtensionsMap).interfaceId 62 | ); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /contracts/protocol/core/state/MixinStorageAccessible.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-3.0-only 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | import {IStorageAccessible} from "../../interfaces/v4/pool/IStorageAccessible.sol"; 5 | 6 | /// @title StorageAccessible - generic base contract that allows callers to access all internal storage. 7 | /// @notice See https://github.com/gnosis/util-contracts/blob/bb5fe5fb5df6d8400998094fb1b32a178a47c3a1/contracts/StorageAccessible.sol 8 | abstract contract MixinStorageAccessible is IStorageAccessible { 9 | /// @inheritdoc IStorageAccessible 10 | function getStorageAt(uint256 offset, uint256 length) public view override returns (bytes memory) { 11 | bytes memory result = new bytes(length * 32); 12 | for (uint256 index = 0; index < length; index++) { 13 | // solhint-disable-next-line no-inline-assembly 14 | assembly { 15 | let word := sload(add(offset, index)) 16 | mstore(add(add(result, 0x20), mul(index, 0x20)), word) 17 | } 18 | } 19 | return result; 20 | } 21 | 22 | /// @inheritdoc IStorageAccessible 23 | function getStorageSlotsAt(uint256[] memory slots) public view override returns (bytes memory) { 24 | // caching for gas savings 25 | uint256 slotsLength = slots.length; 26 | 27 | bytes memory result = new bytes(slotsLength * 32); 28 | for (uint256 index = 0; index < slotsLength; index++) { 29 | uint256 slot = slots[index]; 30 | // solhint-disable-next-line no-inline-assembly 31 | assembly { 32 | let word := sload(slot) 33 | mstore(add(add(result, 0x20), mul(index, 0x20)), word) 34 | } 35 | } 36 | return result; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /contracts/protocol/core/sys/MixinAbstract.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | import {IERC20} from "../../interfaces/IERC20.sol"; 5 | 6 | /// @notice This contract makes it easy for clients to track ERC20. 7 | abstract contract MixinAbstract is IERC20 { 8 | /// @dev Non-implemented ERC20 method. 9 | function transfer(address to, uint256 value) external override returns (bool success) {} 10 | 11 | /// @dev Non-implemented ERC20 method. 12 | function transferFrom(address from, address to, uint256 value) external override returns (bool success) {} 13 | 14 | /// @dev Non-implemented ERC20 method. 15 | function approve(address spender, uint256 value) external override returns (bool success) {} 16 | 17 | /// @dev Non-implemented ERC20 method. 18 | function allowance(address owner, address spender) external view override returns (uint256) {} 19 | } 20 | -------------------------------------------------------------------------------- /contracts/protocol/core/sys/MixinInitializer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | import {MixinImmutables} from "../immutable/MixinImmutables.sol"; 5 | import {MixinStorage} from "../immutable/MixinStorage.sol"; 6 | import {IERC20} from "../../interfaces/IERC20.sol"; 7 | import {IRigoblockPoolProxyFactory} from "../../interfaces/IRigoblockPoolProxyFactory.sol"; 8 | import {ISmartPoolInitializer} from "../../interfaces/v4/pool/ISmartPoolInitializer.sol"; 9 | import {Pool} from "../../libraries/EnumerableSet.sol"; 10 | 11 | abstract contract MixinInitializer is MixinImmutables, MixinStorage { 12 | error BaseTokenDecimals(); 13 | error PoolAlreadyInitialized(); 14 | 15 | modifier onlyUninitialized() { 16 | // pool proxy is always initialized in the constructor, therefore 17 | // empty code means the pool has not been initialized 18 | require(address(this).code.length == 0, PoolAlreadyInitialized()); 19 | _; 20 | } 21 | 22 | /// @inheritdoc ISmartPoolInitializer 23 | /// @dev Cannot be reentered as no non-view call is performed to external contracts. Unlocked is kept for backwards compatibility. 24 | function initializePool() external override onlyUninitialized { 25 | IRigoblockPoolProxyFactory.Parameters memory initParams = IRigoblockPoolProxyFactory(msg.sender).parameters(); 26 | 27 | Pool memory pool = Pool({ 28 | name: initParams.name, 29 | symbol: initParams.symbol, 30 | decimals: 18, 31 | owner: initParams.owner, 32 | unlocked: true, 33 | baseToken: initParams.baseToken 34 | }); 35 | 36 | // overwrite token decimals 37 | if (initParams.baseToken != _ZERO_ADDRESS) { 38 | assert(initParams.baseToken.code.length > 0); 39 | try IERC20(initParams.baseToken).decimals() returns (uint8 decimals) { 40 | // a pool with small decimals could easily underflow. 41 | assert(decimals >= 6); 42 | 43 | // update with the base token's decimals 44 | pool.decimals = decimals; 45 | } catch { 46 | revert BaseTokenDecimals(); 47 | } 48 | } 49 | 50 | // initialize storage 51 | poolWrapper().pool = pool; 52 | emit PoolInitialized(msg.sender, initParams.owner, initParams.baseToken, initParams.name, initParams.symbol); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /contracts/protocol/deps/ExtensionsMapDeployer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0-or-later 2 | pragma solidity 0.8.28; 3 | 4 | import {ExtensionsMap} from "./ExtensionsMap.sol"; 5 | import {IExtensionsMapDeployer} from "../interfaces/IExtensionsMapDeployer.sol"; 6 | import {DeploymentParams, Extensions} from "../types/DeploymentParams.sol"; 7 | 8 | contract ExtensionsMapDeployer is IExtensionsMapDeployer { 9 | address private transient _eApps; 10 | address private transient _eOracle; 11 | address private transient _eUpgrade; 12 | address private transient _wrappedNative; 13 | 14 | /// @inheritdoc IExtensionsMapDeployer 15 | mapping(address deployer => mapping(bytes32 salt => address mapAddress)) public deployedMaps; 16 | 17 | /// @inheritdoc IExtensionsMapDeployer 18 | function deployExtensionsMap(DeploymentParams memory params, bytes32 salt) external override returns (address) { 19 | _eApps = params.extensions.eApps; 20 | _eOracle = params.extensions.eOracle; 21 | _eUpgrade = params.extensions.eUpgrade; 22 | _wrappedNative = params.wrappedNative; 23 | 24 | // Pre-compute the CREATE2 address 25 | salt = keccak256(abi.encode(msg.sender, salt)); 26 | address map = address( 27 | uint160( 28 | uint256( 29 | keccak256( 30 | abi.encodePacked(bytes1(0xff), address(this), salt, keccak256(type(ExtensionsMap).creationCode)) 31 | ) 32 | ) 33 | ) 34 | ); 35 | 36 | // Deploy only if no code exists 37 | if (map.code.length == 0) { 38 | address newMap = address(new ExtensionsMap{salt: salt}()); 39 | assert(newMap == map); 40 | deployedMaps[msg.sender][salt] = map; 41 | } 42 | 43 | return map; 44 | } 45 | 46 | /// @inheritdoc IExtensionsMapDeployer 47 | function parameters() external view override returns (DeploymentParams memory) { 48 | return 49 | DeploymentParams({ 50 | extensions: Extensions({eApps: _eApps, eOracle: _eOracle, eUpgrade: _eUpgrade}), 51 | wrappedNative: _wrappedNative 52 | }); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /contracts/protocol/deps/Kyc.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | /* 3 | 4 | Copyright 2022 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity 0.8.17; 21 | 22 | /// @title Rigoblock KYC contract - Allows whitelisting users. 23 | -------------------------------------------------------------------------------- /contracts/protocol/extensions/adapters/AGovernance.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2023 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | // solhint-disable-next-line 21 | pragma solidity =0.8.17; 22 | 23 | import "./interfaces/IAGovernance.sol"; 24 | 25 | /// @title Governance adapter - A helper contract for interacting with governance. 26 | /// @author Gabriele Rigo - 27 | // solhint-disable-next-line 28 | contract AGovernance is IAGovernance { 29 | address private immutable _governance; 30 | 31 | constructor(address governance) { 32 | _governance = governance; 33 | } 34 | 35 | /// @inheritdoc IAGovernance 36 | function propose(IRigoblockGovernance.ProposedAction[] memory actions, string memory description) 37 | external 38 | override 39 | { 40 | IRigoblockGovernance(_getGovernance()).propose(actions, description); 41 | } 42 | 43 | /// @inheritdoc IAGovernance 44 | function castVote(uint256 proposalId, IRigoblockGovernance.VoteType voteType) external override { 45 | IRigoblockGovernance(_getGovernance()).castVote(proposalId, voteType); 46 | } 47 | 48 | /// @inheritdoc IAGovernance 49 | function execute(uint256 proposalId) external override { 50 | IRigoblockGovernance(_getGovernance()).execute(proposalId); 51 | } 52 | 53 | function _getGovernance() private view returns (address) { 54 | return _governance; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /contracts/protocol/extensions/adapters/AMulticall.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | 3 | // solhint-disable-next-line 4 | pragma solidity 0.8.17; 5 | 6 | import "./interfaces/IAMulticall.sol"; 7 | 8 | /// @title AMulticall - Allows sending mulple transactions to the pool. 9 | /// @notice As per https://github.com/Uniswap/swap-router-contracts/blob/main/contracts/base/MulticallExtended.sol 10 | contract AMulticall is IAMulticall { 11 | modifier checkDeadline(uint256 deadline) { 12 | require(_blockTimestamp() <= deadline, "AMULTICALL_DEADLINE_PAST_ERROR"); 13 | _; 14 | } 15 | 16 | modifier checkPreviousBlockhash(bytes32 previousBlockhash) { 17 | require(blockhash(block.number - 1) == previousBlockhash, "AMULTICALL_BLOCKHASH_ERROR"); 18 | _; 19 | } 20 | 21 | /// @inheritdoc IAMulticall 22 | function multicall(bytes[] calldata data) public override returns (bytes[] memory results) { 23 | results = new bytes[](data.length); 24 | for (uint256 i = 0; i < data.length; i++) { 25 | (bool success, bytes memory result) = address(this).delegatecall(data[i]); 26 | 27 | if (!success) { 28 | // Next 5 lines from https://ethereum.stackexchange.com/a/83577 29 | if (result.length < 68) revert(); 30 | assembly { 31 | result := add(result, 0x04) 32 | } 33 | revert(abi.decode(result, (string))); 34 | } 35 | 36 | results[i] = result; 37 | } 38 | } 39 | 40 | /// @inheritdoc IAMulticall 41 | function multicall(uint256 deadline, bytes[] calldata data) 42 | external 43 | payable 44 | override 45 | checkDeadline(deadline) 46 | returns (bytes[] memory) 47 | { 48 | return multicall(data); 49 | } 50 | 51 | /// @inheritdoc IAMulticall 52 | function multicall(bytes32 previousBlockhash, bytes[] calldata data) 53 | external 54 | payable 55 | override 56 | checkPreviousBlockhash(previousBlockhash) 57 | returns (bytes[] memory) 58 | { 59 | return multicall(data); 60 | } 61 | 62 | /// @dev Method that exists purely to be overridden for tests 63 | /// @return The current block timestamp 64 | function _blockTimestamp() internal view virtual returns (uint256) { 65 | return block.timestamp; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /contracts/protocol/extensions/adapters/AUniswap.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0-or-later 2 | /* 3 | 4 | Copyright 2021-2025 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | // solhint-disable-next-line 21 | pragma solidity 0.8.28; 22 | 23 | import {INonfungiblePositionManager} from "../../../utils/exchanges/uniswap/INonfungiblePositionManager/INonfungiblePositionManager.sol"; 24 | import {IWETH9} from "../../interfaces/IWETH9.sol"; 25 | import {EnumerableSet, AddressSet} from "../../libraries/EnumerableSet.sol"; 26 | import {StorageLib} from "../../libraries/StorageLib.sol"; 27 | import {IAUniswap} from "./interfaces/IAUniswap.sol"; 28 | import {IEOracle} from "./interfaces/IEOracle.sol"; 29 | import {IMinimumVersion} from "./interfaces/IMinimumVersion.sol"; 30 | 31 | /// @title AUniswap - Wraps/unwraps native token using uniswapRouter2 selectors. 32 | /// @author Gabriele Rigo - 33 | contract AUniswap is IAUniswap, IMinimumVersion { 34 | using EnumerableSet for AddressSet; 35 | 36 | string private constant _REQUIRED_VERSION = "4.0.0"; 37 | 38 | address private constant ADDRESS_ZERO = address(0); 39 | 40 | IWETH9 private immutable _weth; 41 | 42 | constructor(address weth) { 43 | _weth = IWETH9(weth); 44 | } 45 | 46 | /// @inheritdoc IMinimumVersion 47 | function requiredVersion() external pure override returns (string memory) { 48 | return _REQUIRED_VERSION; 49 | } 50 | 51 | /// @inheritdoc IAUniswap 52 | function unwrapWETH9(uint256 amountMinimum) external override { 53 | _activateToken(ADDRESS_ZERO); 54 | _weth.withdraw(amountMinimum); 55 | } 56 | 57 | /// @inheritdoc IAUniswap 58 | function unwrapWETH9(uint256 amountMinimum, address /*recipient*/) external override { 59 | _activateToken(ADDRESS_ZERO); 60 | _weth.withdraw(amountMinimum); 61 | } 62 | 63 | /// @inheritdoc IAUniswap 64 | function wrapETH(uint256 value) external override { 65 | if (value > uint256(0)) { 66 | _activateToken(address(_weth)); 67 | _weth.deposit{value: value}(); 68 | } 69 | } 70 | 71 | function _activateToken(address token) private { 72 | AddressSet storage values = StorageLib.activeTokensSet(); 73 | 74 | // update storage with new token 75 | values.addUnique(IEOracle(address(this)), token, StorageLib.pool().baseToken); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /contracts/protocol/extensions/adapters/interfaces/IAGovernance.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2023 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import "../../../../governance/IRigoblockGovernance.sol"; 23 | 24 | interface IAGovernance { 25 | /// @notice Allows to make a proposal to the Rigoblock governance. 26 | /// @param actions Array of tuples of proposed actions. 27 | /// @param description A human-readable description. 28 | function propose(IRigoblockGovernance.ProposedAction[] memory actions, string memory description) external; 29 | 30 | /// @notice Allows a pool to vote on a proposal. 31 | /// @param proposalId Number of the proposal. 32 | /// @param voteType Enum of the vote type. 33 | function castVote(uint256 proposalId, IRigoblockGovernance.VoteType voteType) external; 34 | 35 | /// @notice Allows a pool to execute a proposal. 36 | /// @param proposalId Number of the proposal. 37 | function execute(uint256 proposalId) external; 38 | } 39 | -------------------------------------------------------------------------------- /contracts/protocol/extensions/adapters/interfaces/IAMulticall.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | 3 | pragma solidity >=0.8.0 <0.9.0; 4 | 5 | /// @notice As per https://github.com/Uniswap/swap-router-contracts/blob/main/contracts/interfaces/IMulticallExtended.sol 6 | interface IAMulticall { 7 | /// @notice Enables calling multiple methods in a single call to the contract 8 | /// @param data Array of encoded calls. 9 | /// @return results Array of call responses. 10 | function multicall(bytes[] calldata data) external returns (bytes[] memory results); 11 | 12 | /// @notice Call multiple functions in the current contract and return the data from all of them if they all succeed 13 | /// @dev The `msg.value` should not be trusted for any method callable from multicall. 14 | /// @param deadline The time by which this function must be called before failing 15 | /// @param data The encoded function data for each of the calls to make to this contract 16 | /// @return results The results from each of the calls passed in via data 17 | function multicall(uint256 deadline, bytes[] calldata data) external payable returns (bytes[] memory results); 18 | 19 | /// @notice Call multiple functions in the current contract and return the data from all of them if they all succeed 20 | /// @dev The `msg.value` should not be trusted for any method callable from multicall. 21 | /// @param previousBlockhash The expected parent blockHash 22 | /// @param data The encoded function data for each of the calls to make to this contract 23 | /// @return results The results from each of the calls passed in via data 24 | function multicall(bytes32 previousBlockhash, bytes[] calldata data) 25 | external 26 | payable 27 | returns (bytes[] memory results); 28 | } 29 | -------------------------------------------------------------------------------- /contracts/protocol/extensions/adapters/interfaces/IAStaking.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2022 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | interface IAStaking { 23 | /// @notice Stakes an amount of GRG to own staking pool. Creates staking pool if doesn't exist. 24 | /// @dev Creating staking pool if doesn't exist effectively locks direct call. 25 | /// @param amount Amount of GRG to stake. 26 | function stake(uint256 amount) external; 27 | 28 | /// @notice Undelegates stake for the pool. 29 | /// @param amount Number of GRG units with undelegate. 30 | function undelegateStake(uint256 amount) external; 31 | 32 | /// @notice Unstakes staked undelegated tokens for the pool. 33 | /// @param amount Number of GRG units to unstake. 34 | function unstake(uint256 amount) external; 35 | 36 | /// @notice Withdraws delegator rewards of the pool. 37 | function withdrawDelegatorRewards() external; 38 | } 39 | -------------------------------------------------------------------------------- /contracts/protocol/extensions/adapters/interfaces/IAUniswap.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2022-2025 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | interface IAUniswap { 23 | /// @notice Unwraps the contract's WETH9 balance and sends it to recipient as ETH. 24 | /// @dev The amountMinimum parameter prevents malicious contracts from stealing WETH9 from users. 25 | /// @param amountMinimum The minimum amount of WETH9 to unwrap. 26 | function unwrapWETH9(uint256 amountMinimum) external; 27 | 28 | /// @notice Unwraps ETH from WETH9. 29 | /// @param amountMinimum The minimum amount of WETH9 to unwrap. 30 | /// @param recipient The address to keep same uniswap npm selector. 31 | function unwrapWETH9(uint256 amountMinimum, address recipient) external; 32 | 33 | /// @notice Wraps ETH. 34 | /// @dev Client must wrap if input is native currency. 35 | /// @param value The ETH amount to be wrapped. 36 | function wrapETH(uint256 value) external; 37 | } 38 | -------------------------------------------------------------------------------- /contracts/protocol/extensions/adapters/interfaces/IAUniswapRouter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2025 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import {IPositionManager} from "@uniswap/v4-periphery/src/interfaces/IPositionManager.sol"; 23 | 24 | interface IAUniswapRouter { 25 | /// @notice Executes encoded commands along with provided inputs. Reverts if deadline has expired. 26 | /// @param commands A set of concatenated commands, each 1 byte in length. 27 | /// @param inputs An array of byte strings containing abi encoded inputs for each command. 28 | /// @param deadline The deadline by which the transaction must be executed. 29 | function execute(bytes calldata commands, bytes[] calldata inputs, uint256 deadline) external; 30 | 31 | /// @notice Executes encoded commands along with provided inputs. 32 | /// @param commands A set of concatenated commands, each 1 byte in length. 33 | /// @param inputs An array of byte strings containing abi encoded inputs for each command. 34 | /// @dev Only mint call has access to state, will revert with direct calls unless recipient is explicitly set to this. 35 | function execute(bytes calldata commands, bytes[] calldata inputs) external; 36 | 37 | /// @notice Executes a Uniswap V4 Posm liquidity transaction. 38 | /// @param unlockData Encoded calldata containing actions to be executed. 39 | /// @param deadline Deadline of the transaction. 40 | function modifyLiquidities(bytes calldata unlockData, uint256 deadline) external; 41 | } 42 | -------------------------------------------------------------------------------- /contracts/protocol/extensions/adapters/interfaces/IEApps.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2025 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import {ExternalApp} from "../../../types/ExternalApp.sol"; 23 | 24 | interface IEApps { 25 | /// @notice Returns token balances owned in a set of external contracts. 26 | /// @param packedApplications The uint encoded bitmap flags of the active applications. 27 | /// @return appBalances The arrays of lists of token balances grouped by application type. 28 | function getAppTokenBalances(uint256 packedApplications) external returns (ExternalApp[] memory appBalances); 29 | 30 | /// @notice Returns the pool's Uniswap V4 active liquidity positions. 31 | /// @return tokenIds Array of liquidity position token ids. 32 | function getUniV4TokenIds() external view returns (uint256[] memory tokenIds); 33 | } 34 | -------------------------------------------------------------------------------- /contracts/protocol/extensions/adapters/interfaces/IEOracle.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0-or-later 2 | /* 3 | 4 | Copyright 2025 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | interface IEOracle { 23 | /// @notice Returns the sum of the token amounts converted to a target token. 24 | /// @dev Will first try to convert via cross with chain currency, fallback to direct cross if not available. 25 | /// @param tokens The array of token addresses to be converted. 26 | /// @param amounts The array of amounts to be converted. 27 | /// @param targetToken The address of the target token. 28 | /// @return totalConvertedAmount The total value of converted amount in target token amount. 29 | function convertBatchTokenAmounts( 30 | address[] calldata tokens, 31 | int256[] calldata amounts, 32 | address targetToken 33 | ) external view returns (int256 totalConvertedAmount); 34 | 35 | /// @notice Returns a token amount converted to a target token. 36 | /// @dev Will first try to convert via cross with chain currency, fallback to direct cross if not available. 37 | /// @param token The address of the token to be converted. 38 | /// @param amount The amount to be converted. 39 | /// @param targetToken The address of the target token. 40 | /// @return convertedAmount The value of converted amount in target token amount. 41 | function convertTokenAmount( 42 | address token, 43 | int256 amount, 44 | address targetToken 45 | ) external view returns (int256 convertedAmount); 46 | 47 | /// @notice Returns whether a token has a price feed. 48 | /// @param token The address of the token. 49 | /// @return Boolean the price feed exists. 50 | function hasPriceFeed(address token) external view returns (bool); 51 | 52 | /// @notice Returns token price aginst native currency. 53 | /// @param token The address of the token. 54 | /// @return twap The time weighted average price. 55 | function getTwap(address token) external view returns (int24 twap); 56 | } 57 | -------------------------------------------------------------------------------- /contracts/protocol/extensions/adapters/interfaces/IEUpgrade.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2022-2025 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | interface IEUpgrade { 23 | /// @notice Emitted when pool operator upgrades proxy implementation address. 24 | /// @param implementation Address of the new implementation. 25 | event Upgraded(address indexed implementation); 26 | 27 | /// @notice Allows caller to upgrade pool implementation. 28 | /// @dev Cannot be called directly and in pool is restricted to pool owner. 29 | function upgradeImplementation() external; 30 | 31 | /// @notice Returns the implementation beacon. 32 | /// Address of the beacon. 33 | function getBeacon() external view returns (address); 34 | } 35 | -------------------------------------------------------------------------------- /contracts/protocol/extensions/adapters/interfaces/IMinimumVersion.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2025 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | interface IMinimumVersion { 23 | /// @notice Returns the minimum implementation version to use an external application. 24 | /// @dev Adapters must implement it when modifying proxy state or storage. 25 | /// @return String of the minimum supported version. 26 | function requiredVersion() external view returns (string memory); 27 | } 28 | -------------------------------------------------------------------------------- /contracts/protocol/extensions/adapters/interfaces/IRigoblockExtensions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2022-2025 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import {IAGovernance} from "./IAGovernance.sol"; 23 | import {IAMulticall} from "./IAMulticall.sol"; 24 | import {IAStaking} from "./IAStaking.sol"; 25 | import {IAUniswap} from "./IAUniswap.sol"; 26 | import {IAUniswapRouter} from "./IAUniswapRouter.sol"; 27 | import {IEApps} from "./IEApps.sol"; 28 | import {IEOracle} from "./IEOracle.sol"; 29 | import {IEUpgrade} from "./IEUpgrade.sol"; 30 | 31 | /// @title Rigoblock Extensions Interface - Groups together the extensions' methods. 32 | /// @author Gabriele Rigo - 33 | // solhint-disable-next-line 34 | interface IRigoblockExtensions is 35 | IAGovernance, 36 | IAMulticall, 37 | IAStaking, 38 | IAUniswap, 39 | IAUniswapRouter, 40 | IEApps, 41 | IEOracle, 42 | IEUpgrade 43 | {} 44 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/IExtensionsMap.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2025 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity ^0.8.28; 21 | 22 | /// @title IExtensionsMap - Wraps extensions selectors to addresses. 23 | /// @author Gabriele Rigo - 24 | interface IExtensionsMap { 25 | /// @notice Returns the address of the applications extension contract. 26 | function eApps() external view returns (address); 27 | 28 | /// @notice Returns the address of the oracle extension contract 29 | function eOracle() external view returns (address); 30 | 31 | /// @notice Returns the address of the upgrade extension contract. 32 | function eUpgrade() external view returns (address); 33 | 34 | /// @notice Returns the address of the wrapped native token. 35 | /// @dev It is used for initializing it in the pool implementation immutable storage without passing it in the constructor. 36 | function wrappedNative() external view returns (address); 37 | 38 | /// @notice Returns the map of an extension's selector. 39 | /// @dev Stores all extensions selectors and addresses in its bytecode for gas efficiency. 40 | /// @param selector Selector of the function signature. 41 | /// @return extension Address of the target extensions. 42 | /// @return shouldDelegatecall Boolean if should maintain context of call or not. 43 | function getExtensionBySelector(bytes4 selector) external view returns (address extension, bool shouldDelegatecall); 44 | } 45 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/IExtensionsMapDeployer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0-or-later 2 | pragma solidity ^0.8.28; 3 | 4 | import {DeploymentParams} from "../types/DeploymentParams.sol"; 5 | 6 | interface IExtensionsMapDeployer { 7 | /// @notice Returns the nonce of the deployed ExtensionsMap contract. 8 | /// @dev It is increased only when a new contract is deployed. 9 | /// @param deployer Address of the deployer wallet. 10 | /// @param salt Bytes32 input to allow multi-chain deterministic deployment. 11 | /// @return mapAddress Address of the mapped contract. 12 | function deployedMaps(address deployer, bytes32 salt) external view returns (address mapAddress); 13 | 14 | /// @notice Returns the address of the deployed contract. 15 | /// @dev If the params are unchanged, the address of the already-deployed contract is returned. 16 | function deployExtensionsMap(DeploymentParams memory params, bytes32 salt) external returns (address); 17 | 18 | /// @notice Returns the extensions deployment parameters. 19 | /// @return Tuple of the deployment parameters '(Extensions, address)'. 20 | function parameters() external view returns (DeploymentParams memory); 21 | } 22 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/IKyc.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2017-2018 RigoBlock, Rigo Investment Sagl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | /// @title KycFace - allows interaction with a Kyc provider. 23 | /// @author Gabriele Rigo - 24 | // solhint-disable-next-line 25 | interface IKyc { 26 | /// @notice Returns whether an address has been whitelisted. 27 | /// @param user The address to verify. 28 | /// @return Bool the user is whitelisted. 29 | function isWhitelistedUser(address user) external view returns (bool); 30 | } 31 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/IOracle.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; 5 | import {Observation} from "../types/Observation.sol"; 6 | 7 | interface IOracle { 8 | /// @member index The index of the last written observation for the pool 9 | /// @member cardinality The cardinality of the observations array for the pool 10 | /// @member cardinalityNext The cardinality target of the observations array for the pool, which will replace cardinality when enough observations are written 11 | struct ObservationState { 12 | uint16 index; 13 | uint16 cardinality; 14 | uint16 cardinalityNext; 15 | } 16 | 17 | function increaseCardinalityNext( 18 | PoolKey calldata key, 19 | uint16 cardinalityNext 20 | ) external returns (uint16 cardinalityNextOld, uint16 cardinalityNextNew); 21 | 22 | function getObservation(PoolKey calldata key, uint256 index) external view returns (Observation memory observation); 23 | 24 | function getState(PoolKey calldata key) external view returns (ObservationState memory state); 25 | 26 | function observe( 27 | PoolKey calldata key, 28 | uint32[] calldata secondsAgos 29 | ) external view returns (int48[] memory tickCumulatives, uint144[] memory secondsPerLiquidityCumulativeX128s); 30 | } 31 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/IRigoblockPoolExtended.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2022-2025 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import {ISmartPool} from "../ISmartPool.sol"; 23 | import {IRigoblockExtensions} from "../extensions/adapters/interfaces/IRigoblockExtensions.sol"; 24 | 25 | /// @title Rigoblock Pool Extended Interface - Allows interaction with all the pool's supported methods. 26 | /// @author Gabriele Rigo - 27 | // solhint-disable-next-line 28 | interface IRigoblockPoolExtended is ISmartPool, IRigoblockExtensions {} 29 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/IRigoblockPoolProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0-or-later 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | interface IRigoblockPoolProxy { 5 | /// @notice Emitted when implementation written to proxy storage. 6 | /// @dev Emitted also at first variable initialization. 7 | /// @param newImplementation Address of the new implementation. 8 | event Upgraded(address indexed newImplementation); 9 | } 10 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/IWETH9.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.8.0; 3 | 4 | import {IERC20} from "./IERC20.sol"; 5 | 6 | /// @title Interface for WETH9 7 | interface IWETH9 is IERC20 { 8 | /// @notice Deposit ether to get wrapped ether 9 | function deposit() external payable; 10 | 11 | /// @notice Withdraw wrapped ether to get ether 12 | function withdraw(uint256) external; 13 | } 14 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/pool/IRigoblockV3PoolActions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2022 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | /// @title Rigoblock V3 Pool Actions Interface - Allows interaction with the pool contract. 23 | /// @author Gabriele Rigo - 24 | // solhint-disable-next-line 25 | interface IRigoblockV3PoolActions { 26 | /// @notice Allows a user to mint pool tokens on behalf of an address. 27 | /// @param recipient Address receiving the tokens. 28 | /// @param amountIn Amount of base tokens. 29 | /// @param amountOutMin Minimum amount to be received, prevents pool operator frontrunning. 30 | /// @return recipientAmount Number of tokens minted to recipient. 31 | function mint( 32 | address recipient, 33 | uint256 amountIn, 34 | uint256 amountOutMin 35 | ) external payable returns (uint256 recipientAmount); 36 | 37 | /// @notice Allows a pool holder to burn pool tokens. 38 | /// @param amountIn Number of tokens to burn. 39 | /// @param amountOutMin Minimum amount to be received, prevents pool operator frontrunning. 40 | /// @return netRevenue Net amount of burnt pool tokens. 41 | function burn(uint256 amountIn, uint256 amountOutMin) external returns (uint256 netRevenue); 42 | } 43 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/pool/IRigoblockV3PoolEvents.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | /// @title Rigoblock V3 Pool Events - Declares events of the pool contract. 5 | /// @author Gabriele Rigo - 6 | interface IRigoblockV3PoolEvents { 7 | /// @notice Emitted when a new pool is initialized. 8 | /// @dev Pool is initialized at new pool creation. 9 | /// @param group Address of the factory. 10 | /// @param owner Address of the owner. 11 | /// @param baseToken Address of the base token. 12 | /// @param name String name of the pool. 13 | /// @param symbol String symbol of the pool. 14 | event PoolInitialized( 15 | address indexed group, 16 | address indexed owner, 17 | address indexed baseToken, 18 | string name, 19 | bytes8 symbol 20 | ); 21 | 22 | /// @notice Emitted when new owner is set. 23 | /// @param old Address of the previous owner. 24 | /// @param current Address of the new owner. 25 | event NewOwner(address indexed old, address indexed current); 26 | 27 | /// @notice Emitted when pool operator updates NAV. 28 | /// @param poolOperator Address of the pool owner. 29 | /// @param pool Address of the pool. 30 | /// @param unitaryValue Value of 1 token in wei units. 31 | event NewNav(address indexed poolOperator, address indexed pool, uint256 unitaryValue); 32 | 33 | /// @notice Emitted when pool operator sets new mint fee. 34 | /// @param pool Address of the pool. 35 | /// @param who Address that is sending the transaction. 36 | /// @param transactionFee Number of the new fee in wei. 37 | event NewFee(address indexed pool, address indexed who, uint16 transactionFee); 38 | 39 | /// @notice Emitted when pool operator updates fee collector address. 40 | /// @param pool Address of the pool. 41 | /// @param who Address that is sending the transaction. 42 | /// @param feeCollector Address of the new fee collector. 43 | event NewCollector(address indexed pool, address indexed who, address feeCollector); 44 | 45 | /// @notice Emitted when pool operator updates minimum holding period. 46 | /// @param pool Address of the pool. 47 | /// @param minimumPeriod Number of seconds. 48 | event MinimumPeriodChanged(address indexed pool, uint48 minimumPeriod); 49 | 50 | /// @notice Emitted when pool operator updates the mint/burn spread. 51 | /// @param pool Address of the pool. 52 | /// @param spread Number of the spread in basis points. 53 | event SpreadChanged(address indexed pool, uint16 spread); 54 | 55 | /// @notice Emitted when pool operator sets a kyc provider. 56 | /// @param pool Address of the pool. 57 | /// @param kycProvider Address of the kyc provider. 58 | event KycProviderSet(address indexed pool, address indexed kycProvider); 59 | } 60 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/pool/IRigoblockV3PoolFallback.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | /// @title Rigoblock V3 Pool Fallback Interface - Interface of the fallback method. 5 | /// @author Gabriele Rigo - 6 | interface IRigoblockV3PoolFallback { 7 | /// @notice Delegate calls to pool extension. 8 | /// @dev Delegatecall restricted to owner, staticcall accessible by everyone. 9 | /// @dev Restricting delegatecall to owner effectively locks direct calls. 10 | fallback() external payable; 11 | 12 | /// @notice Allows transfers to pool. 13 | /// @dev Prevents accidental transfer to implementation contract. 14 | receive() external payable; 15 | } 16 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/pool/IRigoblockV3PoolImmutable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | /// @title Rigoblock V3 Pool Immutable - Interface of the pool storage. 5 | /// @author Gabriele Rigo - 6 | interface IRigoblockV3PoolImmutable { 7 | /// @notice Returns a string of the pool version. 8 | /// @return String of the pool implementation version. 9 | function VERSION() external view returns (string memory); 10 | 11 | /// @notice Returns the address of the authority contract. 12 | /// @return Address of the authority contract. 13 | function authority() external view returns (address); 14 | } 15 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/pool/IRigoblockV3PoolInitializer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2022 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | /// @title Rigoblock V3 Pool Initializer Interface - Allows initializing a pool contract. 23 | /// @author Gabriele Rigo - 24 | // solhint-disable-next-line 25 | interface IRigoblockV3PoolInitializer { 26 | /// @notice Initializes to pool storage. 27 | /// @dev Pool can only be initialized at creation, meaning this method cannot be called directly to implementation. 28 | function initializePool() external; 29 | } 30 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/pool/IRigoblockV3PoolOwnerActions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | /// @title Rigoblock V3 Pool Owner Actions Interface - Interface of the owner methods. 5 | /// @author Gabriele Rigo - 6 | interface IRigoblockV3PoolOwnerActions { 7 | /// @notice Allows owner to decide where to receive the fee. 8 | /// @param feeCollector Address of the fee receiver. 9 | function changeFeeCollector(address feeCollector) external; 10 | 11 | /// @notice Allows pool owner to change the minimum holding period. 12 | /// @param minPeriod Time in seconds. 13 | function changeMinPeriod(uint48 minPeriod) external; 14 | 15 | /// @notice Allows pool owner to change the mint/burn spread. 16 | /// @param newSpread Number between 0 and 1000, in basis points. 17 | function changeSpread(uint16 newSpread) external; 18 | 19 | /// @notice Allows pool owner to set/update the user whitelist contract. 20 | /// @dev Kyc provider can be set to null, removing user whitelist requirement. 21 | /// @param kycProvider Address if the kyc provider. 22 | function setKycProvider(address kycProvider) external; 23 | 24 | /// @notice Allows pool owner to set a new owner address. 25 | /// @dev Method restricted to owner. 26 | /// @param newOwner Address of the new owner. 27 | function setOwner(address newOwner) external; 28 | 29 | /// @notice Allows pool owner to set the transaction fee. 30 | /// @param transactionFee Value of the transaction fee in basis points. 31 | function setTransactionFee(uint16 transactionFee) external; 32 | 33 | /// @notice Allows pool owner to set the pool price. 34 | /// @param unitaryValue Value of 1 token in wei units. 35 | function setUnitaryValue(uint256 unitaryValue) external; 36 | } 37 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/pool/IStorageAccessible.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.7.0 <0.9.0; 3 | 4 | /// @title IStorageAccessible - generic base interface that allows callers to access all internal storage. 5 | /// @notice See https://github.com/gnosis/util-contracts/blob/bb5fe5fb5df6d8400998094fb1b32a178a47c3a1/contracts/StorageAccessible.sol 6 | interface IStorageAccessible { 7 | /// @notice Reads `length` bytes of storage in the currents contract. 8 | /// @param offset - the offset in the current contract's storage in words to start reading from. 9 | /// @param length - the number of words (32 bytes) of data to read. 10 | /// @return Bytes string of the bytes that were read. 11 | function getStorageAt(uint256 offset, uint256 length) external view returns (bytes memory); 12 | 13 | /// @notice Reads bytes of storage at different storage locations. 14 | /// @dev Returns a string with values regarless of where they are stored, i.e. variable, mapping or struct. 15 | /// @param slots The array of storage slots to query into. 16 | /// @return Bytes string composite of different storage locations' value. 17 | function getStorageSlotsAt(uint256[] memory slots) external view returns (bytes memory); 18 | } 19 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/v4/pool/ISmartPoolActions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2022-2025 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | /// @title Rigoblock V3 Pool Actions Interface - Allows interaction with the pool contract. 23 | /// @author Gabriele Rigo - 24 | // solhint-disable-next-line 25 | interface ISmartPoolActions { 26 | /// @notice Allows a user to mint pool tokens on behalf of an address. 27 | /// @param recipient Address receiving the tokens. 28 | /// @param amountIn Amount of base tokens. 29 | /// @param amountOutMin Minimum amount to be received, prevents pool operator frontrunning. 30 | /// @return recipientAmount Number of tokens minted to recipient. 31 | function mint( 32 | address recipient, 33 | uint256 amountIn, 34 | uint256 amountOutMin 35 | ) external payable returns (uint256 recipientAmount); 36 | 37 | /// @notice Allows a pool holder to burn pool tokens. 38 | /// @param amountIn Number of tokens to burn. 39 | /// @param amountOutMin Minimum amount to be received, prevents pool operator frontrunning. 40 | /// @return netRevenue Net amount of burnt pool tokens. 41 | function burn(uint256 amountIn, uint256 amountOutMin) external returns (uint256 netRevenue); 42 | 43 | /// @notice Allows a pool holder to burn pool tokens and receive a token other than base token. 44 | /// @param amountIn Number of tokens to burn. 45 | /// @param amountOutMin Minimum amount to be received, prevents pool operator frontrunning. 46 | /// @param tokenOut The token to be received in exchange for pool tokens. 47 | /// @return netRevenue Net amount of burnt pool tokens. 48 | function burnForToken( 49 | uint256 amountIn, 50 | uint256 amountOutMin, 51 | address tokenOut 52 | ) external returns (uint256 netRevenue); 53 | 54 | /// @notice Allows anyone to store an up-to-date pool price. 55 | function updateUnitaryValue() external; 56 | } 57 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/v4/pool/ISmartPoolEvents.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | /// @title Rigoblock V3 Pool Events - Declares events of the pool contract. 5 | /// @author Gabriele Rigo - 6 | interface ISmartPoolEvents { 7 | /// @notice Emitted when a new pool is initialized. 8 | /// @dev Pool is initialized at new pool creation. 9 | /// @param group Address of the factory. 10 | /// @param owner Address of the owner. 11 | /// @param baseToken Address of the base token. 12 | /// @param name String name of the pool. 13 | /// @param symbol String symbol of the pool. 14 | event PoolInitialized( 15 | address indexed group, 16 | address indexed owner, 17 | address indexed baseToken, 18 | string name, 19 | bytes8 symbol 20 | ); 21 | 22 | /// @notice Emitted when new owner is set. 23 | /// @param old Address of the previous owner. 24 | /// @param current Address of the new owner. 25 | event NewOwner(address indexed old, address indexed current); 26 | 27 | /// @notice Emitted when pool operator updates NAV. 28 | /// @param poolOperator Address of the pool owner. 29 | /// @param pool Address of the pool. 30 | /// @param unitaryValue Value of 1 token in wei units. 31 | event NewNav(address indexed poolOperator, address indexed pool, uint256 unitaryValue); 32 | 33 | /// @notice Emitted when pool operator sets new mint fee. 34 | /// @param pool Address of the pool. 35 | /// @param who Address that is sending the transaction. 36 | /// @param transactionFee Number of the new fee in wei. 37 | event NewFee(address indexed pool, address indexed who, uint16 transactionFee); 38 | 39 | /// @notice Emitted when pool operator updates fee collector address. 40 | /// @param pool Address of the pool. 41 | /// @param who Address that is sending the transaction. 42 | /// @param feeCollector Address of the new fee collector. 43 | event NewCollector(address indexed pool, address indexed who, address feeCollector); 44 | 45 | /// @notice Emitted when pool operator updates minimum holding period. 46 | /// @param pool Address of the pool. 47 | /// @param minimumPeriod Number of seconds. 48 | event MinimumPeriodChanged(address indexed pool, uint48 minimumPeriod); 49 | 50 | /// @notice Emitted when pool operator updates the mint/burn spread. 51 | /// @param pool Address of the pool. 52 | /// @param spread Number of the spread in basis points. 53 | event SpreadChanged(address indexed pool, uint16 spread); 54 | 55 | /// @notice Emitted when pool operator sets a kyc provider. 56 | /// @param pool Address of the pool. 57 | /// @param kycProvider Address of the kyc provider. 58 | event KycProviderSet(address indexed pool, address indexed kycProvider); 59 | } 60 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/v4/pool/ISmartPoolFallback.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | /// @title Rigoblock V3 Pool Fallback Interface - Interface of the fallback method. 5 | /// @author Gabriele Rigo - 6 | interface ISmartPoolFallback { 7 | /// @notice Delegate calls to pool extension. 8 | /// @dev Delegatecall restricted to owner, staticcall accessible by everyone. 9 | /// @dev Restricting delegatecall to owner effectively locks direct calls. 10 | fallback() external payable; 11 | 12 | /// @notice Allows transfers to pool. 13 | /// @dev Prevents accidental transfer to implementation contract. 14 | receive() external payable; 15 | } 16 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/v4/pool/ISmartPoolImmutable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | /// @title Rigoblock V3 Pool Immutable - Interface of the pool storage. 5 | /// @author Gabriele Rigo - 6 | interface ISmartPoolImmutable { 7 | /// @notice Returns a string of the pool version. 8 | /// @return String of the pool implementation version. 9 | function VERSION() external view returns (string memory); 10 | 11 | /// @notice Returns the address of the authority contract. 12 | /// @return Address of the authority contract. 13 | function authority() external view returns (address); 14 | 15 | /// @notice Returns the WETH9 contract. 16 | /// @dev Used to convert WETH balances to ETH without executing an oracle call. 17 | /// @return Address of the WETH9 contract. 18 | function wrappedNative() external view returns (address); 19 | } 20 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/v4/pool/ISmartPoolInitializer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2022-2025 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | /// @title Rigoblock V3 Pool Initializer Interface - Allows initializing a pool contract. 23 | /// @author Gabriele Rigo - 24 | // solhint-disable-next-line 25 | interface ISmartPoolInitializer { 26 | /// @notice Initializes to pool storage. 27 | /// @dev Pool can only be initialized at creation, meaning this method cannot be called directly to implementation. 28 | function initializePool() external; 29 | } 30 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/v4/pool/ISmartPoolOwnerActions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | /// @title Rigoblock V3 Pool Owner Actions Interface - Interface of the owner methods. 5 | /// @author Gabriele Rigo - 6 | interface ISmartPoolOwnerActions { 7 | /// @notice Allows owner to decide where to receive the fee. 8 | /// @param feeCollector Address of the fee receiver. 9 | function changeFeeCollector(address feeCollector) external; 10 | 11 | /// @notice Allows pool owner to change the minimum holding period. 12 | /// @param minPeriod Time in seconds. 13 | function changeMinPeriod(uint48 minPeriod) external; 14 | 15 | /// @notice Allows pool owner to change the mint/burn spread. 16 | /// @param newSpread Number between 0 and 1000, in basis points. 17 | function changeSpread(uint16 newSpread) external; 18 | 19 | /// @notice Allows the owner to remove all inactive token and applications. 20 | /// @dev This is the only endpoint that has access to removing a token from the active tokens tuple. 21 | /// @dev Used to reduce cost of mint/burn as more tokens are traded, and allow lower gas for hft. 22 | function purgeInactiveTokensAndApps() external; 23 | 24 | /// @notice Allows pool owner to set/update the user whitelist contract. 25 | /// @dev Kyc provider can be set to null, removing user whitelist requirement. 26 | /// @param kycProvider Address if the kyc provider. 27 | function setKycProvider(address kycProvider) external; 28 | 29 | /// @notice Allows pool owner to set a new owner address. 30 | /// @dev Method restricted to owner. 31 | /// @param newOwner Address of the new owner. 32 | function setOwner(address newOwner) external; 33 | 34 | /// @notice Allows pool owner to set the transaction fee. 35 | /// @param transactionFee Value of the transaction fee in basis points. 36 | function setTransactionFee(uint16 transactionFee) external; 37 | } 38 | -------------------------------------------------------------------------------- /contracts/protocol/interfaces/v4/pool/IStorageAccessible.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | /// @title IStorageAccessible - generic base interface that allows callers to access all internal storage. 5 | /// @notice See https://github.com/gnosis/util-contracts/blob/bb5fe5fb5df6d8400998094fb1b32a178a47c3a1/contracts/StorageAccessible.sol 6 | interface IStorageAccessible { 7 | /// @notice Reads `length` bytes of storage in the currents contract. 8 | /// @param offset - the offset in the current contract's storage in words to start reading from. 9 | /// @param length - the number of words (32 bytes) of data to read. 10 | /// @return Bytes string of the bytes that were read. 11 | function getStorageAt(uint256 offset, uint256 length) external view returns (bytes memory); 12 | 13 | /// @notice Reads bytes of storage at different storage locations. 14 | /// @dev Returns a string with values regarless of where they are stored, i.e. variable, mapping or struct. 15 | /// @param slots The array of storage slots to query into. 16 | /// @return Bytes string composite of different storage locations' value. 17 | function getStorageSlotsAt(uint256[] memory slots) external view returns (bytes memory); 18 | } 19 | -------------------------------------------------------------------------------- /contracts/protocol/libraries/ApplicationsLib.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0-or-later 2 | pragma solidity ^0.8.28; 3 | 4 | struct ApplicationsSlot { 5 | uint256 packedApplications; 6 | } 7 | 8 | library ApplicationsLib { 9 | error ApplicationIndexBitmaskRange(); 10 | 11 | uint256 private constant MAX_ALLOWED_APPLICATIONS = 255; 12 | 13 | /// @notice Sets an application as active in the bitmask. 14 | /// @param self The storage slot where the packed applications are stored. 15 | /// @param appIndex The application to set as active. 16 | function storeApplication(ApplicationsSlot storage self, uint256 appIndex) internal { 17 | require(appIndex < MAX_ALLOWED_APPLICATIONS, ApplicationIndexBitmaskRange()); 18 | uint256 flag = 1 << appIndex; 19 | self.packedApplications |= flag; 20 | } 21 | 22 | /// @notice Removes an application from being active in the bitmask. 23 | /// @param self The storage slot where the packed applications are stored. 24 | /// @param appIndex The application to remove. 25 | function removeApplication(ApplicationsSlot storage self, uint256 appIndex) internal { 26 | require(appIndex < MAX_ALLOWED_APPLICATIONS, ApplicationIndexBitmaskRange()); 27 | uint256 flag = ~(1 << appIndex); 28 | self.packedApplications &= flag; 29 | } 30 | 31 | /// @notice Checks if an application is active in the bitmask. 32 | /// @param packedApplications The bitmap packed active applications flags. 33 | /// @param appIndex The application to check. 34 | /// @return bool Whether the application is active. 35 | function isActiveApplication(uint256 packedApplications, uint256 appIndex) internal pure returns (bool) { 36 | require(appIndex < MAX_ALLOWED_APPLICATIONS, ApplicationIndexBitmaskRange()); 37 | uint256 flag = 1 << appIndex; 38 | return (packedApplications & flag) != 0; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /contracts/protocol/libraries/ReentrancyGuardTransient.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuardTransient.sol) 3 | 4 | pragma solidity ^0.8.24; 5 | 6 | import {TransientSlot} from "./TransientSlot.sol"; 7 | 8 | /** 9 | * @dev Variant of {ReentrancyGuard} that uses transient storage. 10 | * 11 | * NOTE: This variant only works on networks where EIP-1153 is available. 12 | * 13 | * _Available since v5.1._ 14 | */ 15 | abstract contract ReentrancyGuardTransient { 16 | using TransientSlot for *; 17 | 18 | // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff)) 19 | bytes32 private constant REENTRANCY_GUARD_STORAGE = 20 | 0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00; 21 | 22 | /** 23 | * @dev Unauthorized reentrant call. 24 | */ 25 | error ReentrancyGuardReentrantCall(); 26 | 27 | /** 28 | * @dev Prevents a contract from calling itself, directly or indirectly. 29 | * Calling a `nonReentrant` function from another `nonReentrant` 30 | * function is not supported. It is possible to prevent this from happening 31 | * by making the `nonReentrant` function external, and making it call a 32 | * `private` function that does the actual work. 33 | */ 34 | modifier nonReentrant() { 35 | _nonReentrantBefore(); 36 | _; 37 | _nonReentrantAfter(); 38 | } 39 | 40 | function _nonReentrantBefore() private { 41 | // On the first call to nonReentrant, REENTRANCY_GUARD_STORAGE.asBoolean().tload() will be false 42 | if (_reentrancyGuardEntered()) { 43 | revert ReentrancyGuardReentrantCall(); 44 | } 45 | 46 | // Any calls to nonReentrant after this point will fail 47 | REENTRANCY_GUARD_STORAGE.asBoolean().tstore(true); 48 | } 49 | 50 | function _nonReentrantAfter() private { 51 | REENTRANCY_GUARD_STORAGE.asBoolean().tstore(false); 52 | } 53 | 54 | /** 55 | * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a 56 | * `nonReentrant` function in the call stack. 57 | */ 58 | function _reentrancyGuardEntered() internal view returns (bool) { 59 | return REENTRANCY_GUARD_STORAGE.asBoolean().tload(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /contracts/protocol/libraries/SafeTransferLib.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache3.0-or-later 2 | pragma solidity >=0.8.28; 3 | 4 | import {IERC20} from "../interfaces/IERC20.sol"; 5 | 6 | type Currency is address; 7 | 8 | /// @title SafeTransferLib 9 | /// @dev This library allows for safe transfer of tokens without using assembly 10 | library SafeTransferLib { 11 | error ApprovalFailed(address token); 12 | error NativeTransferFailed(); 13 | error TokenTransferFailed(); 14 | error TokenTransferFromFailed(); 15 | error ApprovalTargetIsNotContract(address token); 16 | 17 | function safeTransferNative(address to, uint256 amount) internal { 18 | (bool success, ) = to.call{gas: 2300, value: amount}(""); 19 | require(success, NativeTransferFailed()); 20 | } 21 | 22 | function safeTransfer(address token, address to, uint256 amount) internal { 23 | // solhint-disable-next-line avoid-low-level-calls 24 | (bool success, bytes memory data) = token.call(abi.encodeCall(IERC20.transfer, (to, amount))); 25 | require(success && (data.length == 0 || abi.decode(data, (bool))), TokenTransferFailed()); 26 | } 27 | 28 | function safeTransferFrom(address token, address from, address to, uint256 amount) internal { 29 | // solhint-disable-next-line avoid-low-level-calls 30 | (bool success, bytes memory data) = token.call(abi.encodeCall(IERC20.transferFrom, (from, to, amount))); 31 | require(success && (data.length == 0 || abi.decode(data, (bool))), TokenTransferFromFailed()); 32 | } 33 | 34 | /// @dev Allows approving all ERC20 tokens, forcing approvals when needed. 35 | function safeApprove(address token, address spender, uint256 amount) internal { 36 | // token address sanity check 37 | bool isContract = token.code.length > 0; 38 | require(isContract, ApprovalTargetIsNotContract(token)); 39 | (bool success, bytes memory data) = token.call(abi.encodeCall(IERC20.approve, (spender, amount))); 40 | 41 | if (!success || (data.length != 0 && !abi.decode(data, (bool)))) { 42 | // force approval 43 | (success, data) = token.call(abi.encodeCall(IERC20.approve, (spender, 0))); 44 | (success, data) = token.call(abi.encodeCall(IERC20.approve, (spender, amount))); 45 | 46 | require(success && ((data.length == 0 && isContract) || abi.decode(data, (bool))), ApprovalFailed(token)); 47 | } 48 | } 49 | 50 | function isAddressZero(address target) internal pure returns (bool) { 51 | return target == address(0); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /contracts/protocol/libraries/StorageLib.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0-or-later 2 | pragma solidity ^0.8.28; 3 | 4 | import {TokenIdsSlot} from "../types/Applications.sol"; 5 | import {ApplicationsSlot} from "./ApplicationsLib.sol"; 6 | import {AddressSet, Pool} from "./EnumerableSet.sol"; 7 | 8 | /// @notice A library for extensions to access proxy pre-assigned storage slots. 9 | library StorageLib { 10 | /// @notice persistent storage slot, used to read from proxy storage without having to update implementation 11 | bytes32 private constant _POOL_INIT_SLOT = 0xe48b9bb119adfc3bccddcc581484cc6725fe8d292ebfcec7d67b1f93138d8bd8; 12 | bytes32 private constant _TOKEN_REGISTRY_SLOT = 0x3dcde6752c7421366e48f002bbf8d6493462e0e43af349bebb99f0470a12300d; 13 | bytes32 private constant _APPLICATIONS_SLOT = 0xdc487a67cca3fd0341a90d1b8834103014d2a61e6a212e57883f8680b8f9c831; 14 | 15 | /// @notice Storage expansion not declared in core immutables, but used by extensions and adapters. 16 | // bytes32(uint256(keccak256("pool.proxy.uniV4.tokenIds")) - 1) 17 | bytes32 private constant _UNIV4_TOKEN_IDS_SLOT = 0xd87266b00c1e82928c0b0200ad56e2ee648a35d4e9b273d2ac9533471e3b5d3c; 18 | 19 | function pool() internal pure returns (Pool storage s) { 20 | assembly { 21 | s.slot := _POOL_INIT_SLOT 22 | } 23 | } 24 | 25 | function activeTokensSet() internal pure returns (AddressSet storage s) { 26 | assembly { 27 | s.slot := _TOKEN_REGISTRY_SLOT 28 | } 29 | } 30 | 31 | function uniV4TokenIdsSlot() internal pure returns (TokenIdsSlot storage s) { 32 | assembly { 33 | s.slot := _UNIV4_TOKEN_IDS_SLOT 34 | } 35 | } 36 | 37 | function activeApplications() internal pure returns (ApplicationsSlot storage s) { 38 | assembly { 39 | s.slot := _APPLICATIONS_SLOT 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /contracts/protocol/libraries/StorageSlot.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0-or-later 2 | pragma solidity ^0.8.28; 3 | 4 | library StorageSlot { 5 | struct AddressSlot { 6 | address value; 7 | } 8 | 9 | function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { 10 | assembly { 11 | r.slot := slot 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /contracts/protocol/libraries/TransientStorage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0-or-later 2 | pragma solidity ^0.8.24; 3 | 4 | import {SlotDerivation} from "./SlotDerivation.sol"; 5 | import {TransientSlot} from "./TransientSlot.sol"; 6 | 7 | type Int256 is bytes32; 8 | 9 | library TransientStorage { 10 | using TransientSlot for *; 11 | using SlotDerivation for bytes32; 12 | 13 | bytes32 internal constant _TRANSIENT_BALANCE_SLOT = 14 | bytes32(uint256(keccak256("mixin.value.transient.balance")) - 1); 15 | 16 | bytes32 internal constant _TRANSIENT_TWAP_TICK_SLOT = bytes32(uint256(keccak256("transient.tick.slot")) - 1); 17 | 18 | // Helper functions for tstore operations 19 | /// @notice Stores a mapping of token addresses to int256 values 20 | function store(Int256 slot, address token, int256 value) internal { 21 | Int256.unwrap(slot).deriveMapping(token).asInt256().tstore(value); 22 | } 23 | 24 | function get(Int256 slot, address token) internal view returns (int256) { 25 | return Int256.unwrap(slot).deriveMapping(token).asInt256().tload(); 26 | } 27 | 28 | function storeBalance(address token, int256 balance) internal { 29 | store(Int256.wrap(_TRANSIENT_BALANCE_SLOT), token, balance); 30 | } 31 | 32 | function getBalance(address token) internal view returns (int256) { 33 | return get(Int256.wrap(_TRANSIENT_BALANCE_SLOT), token); 34 | } 35 | 36 | function storeTwap(address token, int24 twap) internal { 37 | store(Int256.wrap(_TRANSIENT_TWAP_TICK_SLOT), token, int256(twap)); 38 | } 39 | 40 | function getTwap(address token) internal view returns (int24) { 41 | return int24(get(Int256.wrap(_TRANSIENT_TWAP_TICK_SLOT), token)); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /contracts/protocol/libraries/VersionLib.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | library VersionLib { 5 | // Compare versions 6 | function isVersionHigherOrEqual( 7 | string memory givenVersion, 8 | string memory requiredVersion 9 | ) internal pure returns (bool) { 10 | uint256[3] memory given = parseVersion(givenVersion); 11 | uint256[3] memory required = parseVersion(requiredVersion); 12 | 13 | // Compare each part 14 | for (uint256 i = 0; i < 3; i++) { 15 | if (given[i] < required[i]) { 16 | return false; 17 | } 18 | if (given[i] > required[i]) { 19 | return true; 20 | } 21 | } 22 | // If all parts are equal, versions are not higher 23 | return true; 24 | } 25 | 26 | // Convert version string to an array of numbers 27 | function parseVersion(string memory _version) private pure returns (uint256[3] memory versionParts) { 28 | bytes memory b = bytes(_version); 29 | 30 | // caching for gas savings 31 | uint256 stringLength = b.length; 32 | uint256 partIndex = 0; 33 | uint256 currentNumber = 0; 34 | 35 | for (uint256 i = 0; i < stringLength; i++) { 36 | if (b[i] == ".") { 37 | versionParts[partIndex] = currentNumber; 38 | partIndex++; 39 | currentNumber = 0; 40 | } else { 41 | currentNumber = currentNumber * 10 + charToUint(b[i]); 42 | } 43 | } 44 | versionParts[partIndex] = currentNumber; 45 | } 46 | 47 | // Helper function to convert a single character to an integer 48 | function charToUint(bytes1 char) private pure returns (uint256) { 49 | uint256 digit = uint256(uint8(char)) - 48; 50 | require(digit < 10, "Not a digit"); 51 | return digit; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /contracts/protocol/types/Applications.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0-or-later 2 | pragma solidity ^0.8.0; 3 | 4 | /// @notice Supported Applications. 5 | /// @dev Preserve order when adding new applications, last one is the counter. 6 | enum Applications { 7 | GRG_STAKING, 8 | UNIV4_LIQUIDITY, 9 | // append new applications here, up to a total of 255 as a theoretical maximum 10 | COUNT 11 | } 12 | 13 | struct TokenIdsSlot { 14 | uint256[] tokenIds; 15 | mapping(uint256 tokenId => uint256 index) positions; 16 | } 17 | -------------------------------------------------------------------------------- /contracts/protocol/types/DeploymentParams.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0-or-later 2 | pragma solidity ^0.8.0; 3 | 4 | struct Extensions { 5 | address eApps; 6 | address eOracle; 7 | address eUpgrade; 8 | } 9 | 10 | struct DeploymentParams { 11 | Extensions extensions; 12 | address wrappedNative; 13 | } 14 | -------------------------------------------------------------------------------- /contracts/protocol/types/ExternalApp.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0-or-later 2 | pragma solidity ^0.8.0; 3 | 4 | struct AppTokenBalance { 5 | address token; 6 | int256 amount; 7 | } 8 | 9 | struct ExternalApp { 10 | AppTokenBalance[] balances; 11 | uint256 appType; // stored as a uint256 to facilityte supporting new apps 12 | } 13 | -------------------------------------------------------------------------------- /contracts/protocol/types/NavComponents.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0-or-later 2 | pragma solidity ^0.8.0; 3 | 4 | struct NavComponents { 5 | uint256 unitaryValue; 6 | uint256 totalSupply; 7 | address baseToken; 8 | uint8 decimals; 9 | } 10 | -------------------------------------------------------------------------------- /contracts/protocol/types/Observation.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0-or-later 2 | pragma solidity ^0.8.0; 3 | 4 | struct Observation { 5 | // the block timestamp of the observation 6 | uint32 blockTimestamp; 7 | // the previous printed tick to calculate the change from time to time 8 | int24 prevTick; 9 | // the tick accumulator, i.e. tick * time elapsed since the pool was first initialized 10 | int48 tickCumulative; 11 | // the seconds per liquidity, i.e. seconds elapsed / max(1, liquidity) since the pool was first initialized 12 | uint144 secondsPerLiquidityCumulativeX128; 13 | // whether or not the observation is initialized 14 | bool initialized; 15 | } 16 | 17 | struct ObservationState { 18 | uint16 index; 19 | uint16 cardinality; 20 | uint16 cardinalityNext; 21 | } 22 | -------------------------------------------------------------------------------- /contracts/rigoToken/interfaces/IInflation.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2017-2019 RigoBlock, Rigo Investment Sagl, 2020 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | /// @title Inflation Interface - Allows interaction with the Inflation contract. 23 | /// @author Gabriele Rigo - 24 | // solhint-disable-next-line 25 | interface IInflation { 26 | /* 27 | * STORAGE 28 | */ 29 | /// @notice Returns the address of the GRG token. 30 | /// @return Address of the Rigo token contract. 31 | function rigoToken() external view returns (address); 32 | 33 | /// @notice Returns the address of the GRG staking proxy. 34 | /// @return Address of the proxy contract. 35 | function stakingProxy() external view returns (address); 36 | 37 | /// @notice Returns the epoch length in seconds. 38 | /// @return Number of seconds. 39 | function epochLength() external view returns (uint48); 40 | 41 | /// @notice Returns epoch slot. 42 | /// @dev Increases by one every new epoch. 43 | /// @return Number of latest epoch slot. 44 | function slot() external view returns (uint32); 45 | 46 | /* 47 | * CORE FUNCTIONS 48 | */ 49 | /// @notice Allows staking proxy to mint rewards. 50 | /// @return mintedInflation Number of allocated tokens. 51 | function mintInflation() external returns (uint256 mintedInflation); 52 | 53 | /* 54 | * CONSTANT PUBLIC FUNCTIONS 55 | */ 56 | /// @notice Returns whether an epoch has ended. 57 | /// @return Bool the epoch has ended. 58 | function epochEnded() external view returns (bool); 59 | 60 | /// @notice Returns the epoch inflation. 61 | /// @return Value of units of GRG minted in an epoch. 62 | function getEpochInflation() external view returns (uint256); 63 | 64 | /// @notice Returns how long until next claim. 65 | /// @return Number in seconds. 66 | function timeUntilNextClaim() external view returns (uint256); 67 | } 68 | -------------------------------------------------------------------------------- /contracts/rigoToken/interfaces/IProofOfPerformance.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2017-2022 RigoBlock, Rigo Investment Sagl, Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | /// @title Proof of Performance Interface - Allows interaction with the PoP contract. 23 | /// @author Gabriele Rigo - 24 | // solhint-disable-next-line 25 | interface IProofOfPerformance { 26 | /* 27 | * CORE FUNCTIONS 28 | */ 29 | /// @dev Credits the pop reward to the Staking Proxy contract. 30 | /// @param targetPool Address of the pool. 31 | function creditPopRewardToStakingProxy(address targetPool) external; 32 | 33 | /* 34 | * CONSTANT PUBLIC FUNCTIONS 35 | */ 36 | /// @dev Returns the proof of performance reward for a pool. 37 | /// @param targetPool Address of the pool. 38 | /// @return Value of the pop reward in Rigo tokens. 39 | function proofOfPerformance(address targetPool) external view returns (uint256); 40 | } 41 | -------------------------------------------------------------------------------- /contracts/rigoToken/interfaces/IRigoToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2017-2018 RigoBlock, Rigo Investment Sagl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | import "../../tokens/ERC20/IERC20.sol"; 23 | 24 | /// @title Rigo Token Interface - Allows interaction with the Rigo token. 25 | /// @author Gabriele Rigo - 26 | // solhint-disable-next-line 27 | interface IRigoToken is IERC20 { 28 | /// @notice Emitted when new tokens have been minted. 29 | /// @param recipient Address receiving the new tokens. 30 | /// @param amount Number of minted units. 31 | event TokenMinted(address indexed recipient, uint256 amount); 32 | 33 | /// @notice Returns the address of the minter. 34 | /// @return Address of the minter. 35 | function minter() external view returns (address); 36 | 37 | /// @notice Returns the address of the Rigoblock Dao. 38 | /// @return Address of the Dao. 39 | function rigoblock() external view returns (address); 40 | 41 | /// @notice Allows minter to create new tokens. 42 | /// @dev Mint method is reserved for minter module. 43 | /// @param recipient Address receiving the new tokens. 44 | /// @param amount Number of minted tokens. 45 | function mintToken(address recipient, uint256 amount) external; 46 | 47 | /// @notice Allows Rigoblock Dao to update minter. 48 | /// @param newAddress Address of the new minter. 49 | function changeMintingAddress(address newAddress) external; 50 | 51 | /// @notice Allows Rigoblock Dao to update its address. 52 | /// @param newAddress Address of the new Dao. 53 | function changeRigoblockAddress(address newAddress) external; 54 | } 55 | -------------------------------------------------------------------------------- /contracts/rigoToken/proofOfPerformance/ProofOfPerformance.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | 3 | /* 4 | 5 | Copyright 2017-2019 RigoBlock, Rigo Investment Sagl, 2020 Rigo Intl. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | 19 | */ 20 | 21 | // solhint-disable-next-line 22 | pragma solidity 0.8.17; 23 | 24 | import {IProofOfPerformance} from "../interfaces/IProofOfPerformance.sol"; 25 | import {IStaking} from "../../staking/interfaces/IStaking.sol"; 26 | import {IStructs} from "../../staking/interfaces/IStructs.sol"; 27 | 28 | /// @title Proof of Performance - Controls parameters of inflation. 29 | /// @author Gabriele Rigo - 30 | // solhint-disable-next-line 31 | contract ProofOfPerformance is IProofOfPerformance { 32 | address private immutable _stakingProxy; 33 | 34 | constructor(address stakingProxy) { 35 | _stakingProxy = stakingProxy; 36 | } 37 | 38 | /// @inheritdoc IProofOfPerformance 39 | function creditPopRewardToStakingProxy(address targetPool) external override { 40 | address stakingProxy = _getStakingProxy(); 41 | uint256 poolLockedBalances = IStaking(stakingProxy) 42 | .getOwnerStakeByStatus(targetPool, IStructs.StakeStatus.DELEGATED) 43 | .currentEpochBalance; 44 | 45 | // if address has locked balances, staking pool exists. 46 | require(poolLockedBalances != uint256(0), "POP_STAKING_POOL_BALANCES_NULL_ERROR"); 47 | 48 | IStaking(stakingProxy).creditPopReward(targetPool, poolLockedBalances); 49 | } 50 | 51 | /// @inheritdoc IProofOfPerformance 52 | function proofOfPerformance(address targetPool) external view override returns (uint256) { 53 | return 54 | IStaking(_getStakingProxy()) 55 | .getOwnerStakeByStatus(targetPool, IStructs.StakeStatus.DELEGATED) 56 | .currentEpochBalance; 57 | } 58 | 59 | function _getStakingProxy() private view returns (address) { 60 | return _stakingProxy; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /contracts/rigoToken/rigoToken/RigoToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2017-2018 RigoBlock, Rigo Investment Sagl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity 0.8.17; 21 | 22 | import {UnlimitedAllowanceToken} from "../../tokens/UnlimitedAllowanceToken/UnlimitedAllowanceToken.sol"; 23 | import "../interfaces/IRigoToken.sol"; 24 | 25 | /// @title Rigo Token - Rules of the Rigo token. 26 | /// @author Gabriele Rigo - 27 | /// @notice UnlimitedAllowanceToken is ERC20 28 | contract RigoToken is IRigoToken, UnlimitedAllowanceToken { 29 | /* solhint-disable const-name-snakecase */ 30 | string public constant name = "Rigo Token"; 31 | string public constant symbol = "GRG"; 32 | uint8 public constant decimals = 18; 33 | 34 | /* solhint-enable const-name-snakecase */ 35 | 36 | /// @inheritdoc IRigoToken 37 | address public override minter; 38 | 39 | /// @inheritdoc IRigoToken 40 | address public override rigoblock; 41 | 42 | /* 43 | * MODIFIERS 44 | */ 45 | modifier onlyMinter() { 46 | require(msg.sender == minter); 47 | _; 48 | } 49 | 50 | modifier onlyRigoblock() { 51 | require(msg.sender == rigoblock); 52 | _; 53 | } 54 | 55 | constructor( 56 | address setMinter, 57 | address setRigoblock, 58 | address grgHolder 59 | ) { 60 | minter = setMinter; 61 | rigoblock = setRigoblock; 62 | totalSupply = 1e25; // 10 million tokens, 18 decimals 63 | _balances[grgHolder] = totalSupply; 64 | } 65 | 66 | /* 67 | * CORE FUNCTIONS 68 | */ 69 | /// @inheritdoc IRigoToken 70 | function mintToken(address recipient, uint256 amount) external override onlyMinter { 71 | _balances[recipient] += amount; 72 | totalSupply += amount; 73 | emit TokenMinted(recipient, amount); 74 | } 75 | 76 | /// @inheritdoc IRigoToken 77 | function changeMintingAddress(address newAddress) external override onlyRigoblock { 78 | minter = newAddress; 79 | } 80 | 81 | /// @inheritdoc IRigoToken 82 | function changeRigoblockAddress(address newAddress) external override onlyRigoblock { 83 | rigoblock = newAddress; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /contracts/staking/Staking.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | 3 | /* 4 | 5 | Original work Copyright 2019 ZeroEx Intl. 6 | Modified work Copyright 2020-2022 Rigo Intl. 7 | 8 | Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | Unless required by applicable law or agreed to in writing, software 15 | distributed under the License is distributed on an "AS IS" BASIS, 16 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | See the License for the specific language governing permissions and 18 | limitations under the License. 19 | 20 | */ 21 | 22 | // solhint-disable-next-line 23 | pragma solidity 0.8.17; 24 | 25 | import "./interfaces/IStaking.sol"; 26 | import "./sys/MixinParams.sol"; 27 | import "./stake/MixinStake.sol"; 28 | import "./rewards/MixinPopRewards.sol"; 29 | 30 | contract Staking is IStaking, MixinParams, MixinStake, MixinPopRewards { 31 | /// @notice Setting owner to null address prevents admin direct calls to implementation. 32 | /// @dev Initializing immutable implementation address is used to allow delegatecalls only. 33 | /// @dev Direct calls to the implementation contract are effectively locked. 34 | /// @param grgVault Address of the Grg vault. 35 | /// @param poolRegistry Address of the RigoBlock pool registry. 36 | /// @param rigoToken Address of the Grg token. 37 | constructor( 38 | address grgVault, 39 | address poolRegistry, 40 | address rigoToken 41 | ) Authorizable(address(0)) MixinDeploymentConstants(grgVault, poolRegistry, rigoToken) {} 42 | 43 | /// @notice Initialize storage owned by this contract. 44 | /// @dev This function should not be called directly. 45 | /// @dev The StakingProxy contract will call it in `attachStakingContract()`. 46 | function init() public override onlyAuthorized { 47 | // DANGER! When performing upgrades, take care to modify this logic 48 | // to prevent accidentally clearing prior state. 49 | _initMixinScheduler(); 50 | _initMixinParams(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /contracts/staking/immutable/MixinConstants.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Original work Copyright 2019 ZeroEx Intl. 5 | Modified work Copyright 2020-2022 Rigo Intl. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | 19 | */ 20 | 21 | pragma solidity >=0.8.0 <0.9.0; 22 | 23 | abstract contract MixinConstants { 24 | // 100% in parts-per-million. 25 | uint32 internal constant _PPM_DENOMINATOR = 10**6; 26 | 27 | bytes32 internal constant _NIL_POOL_ID = 0x0000000000000000000000000000000000000000000000000000000000000000; 28 | 29 | address internal constant _NIL_ADDRESS = 0x0000000000000000000000000000000000000000; 30 | 31 | uint256 internal constant _MIN_TOKEN_VALUE = 10**18; 32 | } 33 | -------------------------------------------------------------------------------- /contracts/staking/immutable/MixinDeploymentConstants.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Original work Copyright 2019 ZeroEx Intl. 5 | Modified work Copyright 2020-2022 Rigo Intl. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | 19 | */ 20 | 21 | pragma solidity >=0.8.0 <0.9.0; 22 | 23 | import {IGrgVault as GrgVault} from "../interfaces/IGrgVault.sol"; 24 | import "../interfaces/IStaking.sol"; 25 | import {IPoolRegistry as PoolRegistry} from "../../protocol/interfaces/IPoolRegistry.sol"; 26 | import {IRigoToken as RigoToken} from "../../rigoToken/interfaces/IRigoToken.sol"; 27 | 28 | // solhint-disable separate-by-one-line-in-contract 29 | abstract contract MixinDeploymentConstants is IStaking { 30 | // we store this address in the bytecode to being able to prevent direct calls to the implementation. 31 | address internal immutable _implementation; 32 | 33 | address private immutable _inflationL2; 34 | address private immutable _rigoToken; 35 | address private immutable _grgVault; 36 | address private immutable _poolRegistry; 37 | 38 | constructor( 39 | address grgVault, 40 | address poolRegistry, 41 | address rigoToken 42 | ) { 43 | _grgVault = grgVault; 44 | _poolRegistry = poolRegistry; 45 | _rigoToken = rigoToken; 46 | _implementation = address(this); 47 | uint256 chainId = block.chainid; 48 | address inflationL2 = address(0); 49 | 50 | // we do not overwrite in test environment as we want to separately handle inflationL2 within the tests 51 | if (chainId != 1 && chainId != 5 && chainId != 31337) { 52 | inflationL2 = 0x3A0C479A2715cc01bC3f744F74Efd45f40f8Dad6; 53 | } 54 | 55 | _inflationL2 = inflationL2; 56 | } 57 | 58 | /// @inheritdoc IStaking 59 | function getGrgContract() public view virtual override returns (RigoToken) { 60 | return RigoToken(_rigoToken); 61 | } 62 | 63 | /// @inheritdoc IStaking 64 | function getGrgVault() public view virtual override returns (GrgVault) { 65 | return GrgVault(_grgVault); 66 | } 67 | 68 | /// @inheritdoc IStaking 69 | function getPoolRegistry() public view virtual override returns (PoolRegistry) { 70 | return PoolRegistry(_poolRegistry); 71 | } 72 | 73 | function _getInflation() internal view returns (address) { 74 | return (_inflationL2 != address(0) ? _inflationL2 : getGrgContract().minter()); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /contracts/staking/interfaces/IStakingProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Original work Copyright 2019 ZeroEx Intl. 5 | Modified work Copyright 2020-2022 Rigo Intl. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | 19 | */ 20 | 21 | pragma solidity >=0.8.0 <0.9.0; 22 | 23 | import "./IStructs.sol"; 24 | 25 | interface IStakingProxy { 26 | /// @notice Emitted by StakingProxy when a staking contract is attached. 27 | /// @param newStakingContractAddress Address of newly attached staking contract. 28 | event StakingContractAttachedToProxy(address newStakingContractAddress); 29 | 30 | /// @notice Emitted by StakingProxy when a staking contract is detached. 31 | event StakingContractDetachedFromProxy(); 32 | 33 | /// @notice Attach a staking contract; future calls will be delegated to the staking contract. 34 | /// @dev Note that this is callable only by an authorized address. 35 | /// @param stakingImplementation Address of staking contract. 36 | function attachStakingContract(address stakingImplementation) external; 37 | 38 | /// @notice Detach the current staking contract. 39 | /// @dev Note that this is callable only by an authorized address. 40 | function detachStakingContract() external; 41 | 42 | /// @notice Batch executes a series of calls to the staking contract. 43 | /// @param data An array of data that encodes a sequence of functions to call in the staking contracts. 44 | function batchExecute(bytes[] calldata data) external returns (bytes[] memory batchReturnData); 45 | 46 | /// @notice Asserts initialziation parameters are correct. 47 | /// @dev Asserts that an epoch is between 5 and 30 days long. 48 | /// @dev Asserts that 0 < cobb douglas alpha value <= 1. 49 | /// @dev Asserts that a stake weight is <= 100%. 50 | /// @dev Asserts that pools allow >= 1 maker. 51 | /// @dev Asserts that all addresses are initialized. 52 | function assertValidStorageParams() external view; 53 | } 54 | -------------------------------------------------------------------------------- /contracts/staking/interfaces/IStorageInit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Original work Copyright 2019 ZeroEx Intl. 5 | Modified work Copyright 2020-2022 Rigo Intl. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | 19 | */ 20 | 21 | pragma solidity >=0.8.0 <0.9.0; 22 | 23 | interface IStorageInit { 24 | /// @notice Initialize storage owned by this contract. 25 | function init() external; 26 | } 27 | -------------------------------------------------------------------------------- /contracts/staking/libs/LibSafeDowncast.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Original work Copyright 2019 ZeroEx Intl. 5 | Modified work Copyright 2020 Rigo Intl. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | 19 | */ 20 | 21 | pragma solidity >=0.8.0 <0.9.0; 22 | 23 | library LibSafeDowncast { 24 | /// @dev Safely downcasts to a uint96 25 | /// Note that this reverts if the input value is too large. 26 | function downcastToUint96(uint256 a) internal pure returns (uint96 b) { 27 | b = uint96(a); 28 | require(uint256(b) == a, "VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT96"); 29 | return b; 30 | } 31 | 32 | /// @dev Safely downcasts to a uint64 33 | /// Note that this reverts if the input value is too large. 34 | function downcastToUint64(uint256 a) internal pure returns (uint64 b) { 35 | b = uint64(a); 36 | require(uint256(b) == a, "VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT64"); 37 | return b; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /contracts/staking/rewards/MixinPopManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Original work Copyright 2019 ZeroEx Intl. 5 | Modified work Copyright 2020-2022 Rigo Intl. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | 19 | */ 20 | 21 | pragma solidity >=0.8.0 <0.9.0; 22 | 23 | import "../interfaces/IStakingEvents.sol"; 24 | import "../interfaces/IStaking.sol"; 25 | import "../immutable/MixinStorage.sol"; 26 | 27 | abstract contract MixinPopManager is IStaking, IStakingEvents, MixinStorage { 28 | /// @inheritdoc IStaking 29 | function addPopAddress(address addr) external override onlyAuthorized { 30 | require(!validPops[addr], "STAKING_POP_ALREADY_REGISTERED_ERROR"); 31 | validPops[addr] = true; 32 | emit PopAdded(addr); 33 | } 34 | 35 | /// @inheritdoc IStaking 36 | function removePopAddress(address addr) external override onlyAuthorized { 37 | require(validPops[addr], "STAKING_POP_NOT_REGISTERED_ERROR"); 38 | validPops[addr] = false; 39 | emit PopRemoved(addr); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /contracts/staking/sys/MixinAbstract.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Original work Copyright 2019 ZeroEx Intl. 5 | Modified work Copyright 2020-2022 Rigo Intl. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | 19 | */ 20 | 21 | pragma solidity >=0.8.0 <0.9.0; 22 | 23 | /// @dev Exposes some internal functions from various contracts to avoid 24 | /// cyclical dependencies. 25 | abstract contract MixinAbstract { 26 | /// @dev Computes the reward owed to a pool during finalization. 27 | /// Does nothing if the pool is already finalized. 28 | /// @param poolId The pool's ID. 29 | /// @return totalReward The total reward owed to a pool. 30 | /// @return membersStake The total stake for all non-operator members in 31 | /// this pool. 32 | function _getUnfinalizedPoolRewards(bytes32 poolId) 33 | internal 34 | view 35 | virtual 36 | returns (uint256 totalReward, uint256 membersStake); 37 | 38 | /// @dev Asserts that a pool has been finalized last epoch. 39 | /// @param poolId The id of the pool that should have been finalized. 40 | function _assertPoolFinalizedLastEpoch(bytes32 poolId) internal view virtual; 41 | } 42 | -------------------------------------------------------------------------------- /contracts/staking/sys/MixinScheduler.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Original work Copyright 2019 ZeroEx Intl. 5 | Modified work Copyright 2020-2022 Rigo Intl. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | 19 | */ 20 | 21 | pragma solidity >=0.8.0 <0.9.0; 22 | 23 | import "../immutable/MixinStorage.sol"; 24 | import "../interfaces/IStakingEvents.sol"; 25 | import "../interfaces/IStaking.sol"; 26 | 27 | abstract contract MixinScheduler is IStaking, IStakingEvents, MixinStorage { 28 | /// @inheritdoc IStaking 29 | function getCurrentEpochEarliestEndTimeInSeconds() public view override returns (uint256) { 30 | return currentEpochStartTimeInSeconds + epochDurationInSeconds; 31 | } 32 | 33 | /// @dev Initializes state owned by this mixin. 34 | /// Fails if state was already initialized. 35 | function _initMixinScheduler() internal { 36 | // assert the current values before overwriting them. 37 | _assertSchedulerNotInitialized(); 38 | 39 | // solhint-disable-next-line 40 | currentEpochStartTimeInSeconds = block.timestamp; 41 | currentEpoch = 1; 42 | } 43 | 44 | /// @dev Moves to the next epoch, given the current epoch period has ended. 45 | /// Time intervals that are measured in epochs (like timeLocks) are also incremented, given 46 | /// their periods have ended. 47 | function _goToNextEpoch() internal { 48 | // get current timestamp 49 | // solhint-disable-next-line not-rely-on-time 50 | uint256 currentBlockTimestamp = block.timestamp; 51 | 52 | // validate that we can increment the current epoch 53 | uint256 epochEndTime = getCurrentEpochEarliestEndTimeInSeconds(); 54 | require(epochEndTime <= currentBlockTimestamp, "STAKING_TIMESTAMP_TOO_LOW_ERROR"); 55 | 56 | // incremment epoch 57 | uint256 nextEpoch = currentEpoch + 1; 58 | currentEpoch = nextEpoch; 59 | currentEpochStartTimeInSeconds = currentBlockTimestamp; 60 | } 61 | 62 | /// @dev Assert scheduler state before initializing it. 63 | /// This must be updated for each migration. 64 | function _assertSchedulerNotInitialized() internal view { 65 | require(currentEpochStartTimeInSeconds == 0, "STAKING_SCHEDULER_ALREADY_INITIALIZED_ERROR"); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /contracts/test/MockOwned.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | 3 | pragma solidity >0.8.0 <0.9.0; 4 | 5 | import "../governance/interfaces/IRigoblockGovernanceFactory.sol"; 6 | 7 | contract MockOwned { 8 | function owner() external view returns (address) { 9 | return address(this); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /contracts/test/MockPermit2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | 3 | pragma solidity 0.8.17; 4 | 5 | import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol"; 6 | 7 | library Allowance { 8 | function updateAmountAndExpiration( 9 | IAllowanceTransfer.PackedAllowance storage allowed, 10 | uint160 amount, 11 | uint48 expiration 12 | ) internal { 13 | // If the inputted expiration is 0, the allowance only lasts the duration of the block. 14 | allowed.expiration = expiration == 0 ? uint48(block.timestamp) : expiration; 15 | allowed.amount = amount; 16 | } 17 | } 18 | 19 | contract MockPermit2 { 20 | event Approval( 21 | address indexed owner, 22 | address indexed token, 23 | address indexed spender, 24 | uint160 amount, 25 | uint48 expiration 26 | ); 27 | 28 | using Allowance for IAllowanceTransfer.PackedAllowance; 29 | 30 | mapping(address => mapping(address => mapping(address => IAllowanceTransfer.PackedAllowance))) public allowance; 31 | 32 | function approve(address token, address spender, uint160 amount, uint48 expiration) external { 33 | IAllowanceTransfer.PackedAllowance storage allowed = allowance[msg.sender][token][spender]; 34 | allowed.updateAmountAndExpiration(amount, expiration); 35 | emit Approval(msg.sender, token, spender, amount, expiration); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /contracts/test/MockStrategy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | 3 | pragma solidity >0.8.0 <0.9.0; 4 | 5 | import "../governance/interfaces/IRigoblockGovernanceFactory.sol"; 6 | 7 | contract MockStrategy { 8 | function assertValidInitParams(IRigoblockGovernanceFactory.Parameters memory params) external view {} 9 | } 10 | -------------------------------------------------------------------------------- /contracts/test/MockUniUniversalRouter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0-or-later 2 | 3 | pragma solidity 0.8.28; 4 | 5 | contract MockUniUniversalRouter { 6 | event UniCallExecuted(address caller); 7 | 8 | string public constant requiredVersion = "4.0.0"; 9 | address public immutable univ4Posm; 10 | 11 | constructor(address univ4PosmAddress) { 12 | univ4Posm = univ4PosmAddress; 13 | } 14 | 15 | function execute(bytes calldata /*commands*/, bytes[] calldata /*inputs*/, uint256 /*deadline*/) external payable { 16 | emit UniCallExecuted(msg.sender); 17 | } 18 | 19 | function execute(bytes calldata /*commands*/, bytes[] calldata /*inputs*/) external payable { 20 | emit UniCallExecuted(msg.sender); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /contracts/test/TestCobbDouglas.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | 3 | pragma solidity >0.7.0 <0.9.0; 4 | 5 | import "../staking/libs/LibCobbDouglas.sol"; 6 | 7 | contract TestCobbDouglas { 8 | function getCobbDouglasReward( 9 | uint256 totalRewards, 10 | uint256 fees, 11 | uint256 totalFees, 12 | uint256 stake, 13 | uint256 totalStake, 14 | uint32 alphaNumerator, 15 | uint32 alphaDenominator 16 | ) external pure returns (uint256 rewards) { 17 | rewards = LibCobbDouglas.cobbDouglas( 18 | totalRewards, 19 | fees, 20 | totalFees, 21 | stake, 22 | totalStake, 23 | alphaNumerator, 24 | alphaDenominator 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /contracts/test/TestLibFixedMath.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | 3 | pragma solidity >0.7.0 <0.9.0; 4 | 5 | import "../staking/libs/LibFixedMath.sol"; 6 | 7 | contract TestLibFixedMath { 8 | function mul(int256 a, int256 b) external pure returns (int256 c) { 9 | c = LibFixedMath.mul(a, b); 10 | } 11 | 12 | function div(int256 a, int256 b) external pure returns (int256 c) { 13 | c = LibFixedMath.div(a, b); 14 | } 15 | 16 | function mulDiv(int256 a, int256 n, int256 d) external pure returns (int256 c) { 17 | c = LibFixedMath.mulDiv(a, n, d); 18 | } 19 | 20 | function uintMul(int256 f, uint256 u) external pure returns (uint256) { 21 | return LibFixedMath.uintMul(f, u); 22 | } 23 | 24 | function toFixed(uint256 n, uint256 d) external pure returns (int256 f) { 25 | return LibFixedMath.toFixed(n, d); 26 | } 27 | 28 | function ln(int256 x) external pure returns (int256 r) { 29 | return LibFixedMath.ln(x); 30 | } 31 | 32 | function exp(int256 x) external pure returns (int256 r) { 33 | return LibFixedMath.exp(x); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /contracts/test/TestLibSafeDowncast.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | 3 | pragma solidity >0.7.0 <0.9.0; 4 | 5 | import "../staking/libs/LibSafeDowncast.sol"; 6 | 7 | contract TestLibSafeDowncast { 8 | function downcastToUint96(uint256 a) external pure returns (uint96 b) { 9 | b = LibSafeDowncast.downcastToUint96(a); 10 | } 11 | 12 | function downcastToUint64(uint256 a) external pure returns (uint64 b) { 13 | b = LibSafeDowncast.downcastToUint64(a); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /contracts/test/TestReentrancyAttack.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | import {ISmartPool} from "../protocol/ISmartPool.sol"; 5 | 6 | contract TestReentrancyAttack { 7 | address private immutable RIGOBLOCK_POOL; 8 | uint256 public count = 0; 9 | uint256 private maxLoopCount = 2; 10 | 11 | constructor(address rigoblockPool) { 12 | RIGOBLOCK_POOL = rigoblockPool; 13 | } 14 | 15 | function setMaxCount(uint256 maxCount) external { 16 | maxLoopCount = maxCount; 17 | } 18 | 19 | function mintPool() public { 20 | count += 1; 21 | if (count <= maxLoopCount) { 22 | try ISmartPool(payable(RIGOBLOCK_POOL)).mint(address(this), 1e19, 1) {} catch Error(string memory reason) { 23 | revert(reason); 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /contracts/test/TestSafeTransferLib.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | import {SafeTransferLib} from "../protocol/libraries/SafeTransferLib.sol"; 5 | 6 | contract TestSafeTransferLib { 7 | event Approval(address indexed owner, address indexed spender, uint256 value); 8 | mapping(address => mapping(address => uint256)) public allowed; 9 | 10 | function testForceApprove(address _spender, uint256 _value) public { 11 | SafeTransferLib.safeApprove(address(this), _spender, _value); 12 | } 13 | 14 | function approve(address _spender, uint256 _value) public { 15 | require(!((_value != 0) && (allowed[msg.sender][_spender] != 0))); 16 | 17 | allowed[msg.sender][_spender] = _value; 18 | emit Approval(msg.sender, _spender, _value); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /contracts/tokens/ERC20/ERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | import {IERC20} from "./IERC20.sol"; 5 | 6 | abstract contract ERC20 is IERC20 { 7 | function transfer(address to, uint256 value) external override returns (bool success) { 8 | require(_balances[msg.sender] >= value && _balances[to] + value > _balances[to]); 9 | _balances[msg.sender] -= value; 10 | _balances[to] += value; 11 | emit Transfer(msg.sender, to, value); 12 | return true; 13 | } 14 | 15 | function transferFrom( 16 | address from, 17 | address to, 18 | uint256 value 19 | ) external virtual override returns (bool success) { 20 | require( 21 | _balances[from] >= value && _allowed[from][msg.sender] >= value && _balances[to] + value > _balances[to] 22 | ); 23 | _balances[to] += value; 24 | _balances[from] -= value; 25 | _allowed[from][msg.sender] -= value; 26 | emit Transfer(from, to, value); 27 | return true; 28 | } 29 | 30 | function approve(address spender, uint256 value) external override returns (bool success) { 31 | _allowed[msg.sender][spender] = value; 32 | emit Approval(msg.sender, spender, value); 33 | return true; 34 | } 35 | 36 | function balanceOf(address owner) external view override returns (uint256) { 37 | return _balances[owner]; 38 | } 39 | 40 | function allowance(address owner, address spender) external view override returns (uint256) { 41 | return _allowed[owner][spender]; 42 | } 43 | 44 | uint256 public override totalSupply; 45 | mapping(address => uint256) internal _balances; 46 | mapping(address => mapping(address => uint256)) internal _allowed; 47 | } 48 | -------------------------------------------------------------------------------- /contracts/tokens/ERC20/IERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.5.0; 3 | 4 | interface IERC20 { 5 | /// @notice Emitted when a token is transferred. 6 | /// @param from Address transferring the tokens. 7 | /// @param to Address receiving the tokens. 8 | /// @param value Number of token units. 9 | event Transfer(address indexed from, address indexed to, uint256 value); 10 | 11 | /// @notice Emitted when a token holder sets and approval. 12 | /// @param owner Address of the account setting the approval. 13 | /// @param spender Address of the allowed account. 14 | /// @param value Number of approved units. 15 | event Approval(address indexed owner, address indexed spender, uint256 value); 16 | 17 | /// @notice Transfers token from holder to another address. 18 | /// @param to Address to send tokens to. 19 | /// @param value Number of token units to send. 20 | /// @return success Bool the transaction was successful. 21 | function transfer(address to, uint256 value) external returns (bool success); 22 | 23 | /// @notice Allows spender to transfer tokens from the holder. 24 | /// @param from Address of the token holder. 25 | /// @param to Address to send tokens to. 26 | /// @param value Number of units to transfer. 27 | /// @return success Bool the transaction was successful. 28 | function transferFrom( 29 | address from, 30 | address to, 31 | uint256 value 32 | ) external returns (bool success); 33 | 34 | /// @notice Allows a holder to approve a spender. 35 | /// @param spender Address of the token spender. 36 | /// @param value Number of units to be approved. 37 | /// @return success Bool the transaction was successful. 38 | function approve(address spender, uint256 value) external returns (bool success); 39 | 40 | /// @notice Returns token balance for an address. 41 | /// @param who Address to query balance for. 42 | /// @return Number of units held. 43 | function balanceOf(address who) external view returns (uint256); 44 | 45 | /// @notice Returns token allowance of an address to another address. 46 | /// @param owner Address of token hodler. 47 | /// @param spender Address of the token spender. 48 | /// @return Number of allowed units. 49 | function allowance(address owner, address spender) external view returns (uint256); 50 | 51 | /// @notice Returns the total supply of the token. 52 | /// @return Number of issued units. 53 | function totalSupply() external view returns (uint256); 54 | } 55 | -------------------------------------------------------------------------------- /contracts/tokens/UnlimitedAllowanceToken/UnlimitedAllowanceToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | import {ERC20} from "../ERC20/ERC20.sol"; 5 | 6 | abstract contract UnlimitedAllowanceToken is ERC20 { 7 | uint256 private constant _MAX_UINT = type(uint256).max; 8 | 9 | /// @dev ERC20 transferFrom, modified such that an allowance of _MAX_UINT represents an unlimited allowance. 10 | /// @param from Address to transfer from. 11 | /// @param to Address to transfer to. 12 | /// @param value Amount to transfer. 13 | /// @return Success of transfer. 14 | function transferFrom( 15 | address from, 16 | address to, 17 | uint256 value 18 | ) external override returns (bool) { 19 | uint256 allowance = _allowed[from][msg.sender]; 20 | require(_balances[from] >= value && allowance >= value && _balances[to] + value >= _balances[to]); 21 | _balances[to] += value; 22 | _balances[from] -= value; 23 | if (allowance < _MAX_UINT) { 24 | _allowed[from][msg.sender] -= value; 25 | } 26 | emit Transfer(from, to, value); 27 | return true; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /contracts/utils/0xUtils/ERC20Proxy/MAuthorizable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2018 ZeroEx Intl. 2022 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity 0.8.17; 21 | 22 | import "../interfaces/IAuthorizable.sol"; 23 | 24 | abstract contract MAuthorizable is IAuthorizable { 25 | /// @dev Only authorized addresses can invoke functions with this modifier. 26 | modifier onlyAuthorized() virtual { 27 | revert(); 28 | _; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /contracts/utils/0xUtils/IAssetProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Original work Copyright 2019 ZeroEx Intl. 5 | Modified work Copyright 2020 Rigo Intl. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | 19 | */ 20 | 21 | pragma solidity >=0.5.4 <0.9.0; 22 | 23 | abstract contract IAssetProxy { 24 | /// @dev Transfers assets. Either succeeds or throws. 25 | /// @param assetData Byte array encoded for the respective asset proxy. 26 | /// @param from Address to transfer asset from. 27 | /// @param to Address to transfer asset to. 28 | /// @param amount Amount of asset to transfer. 29 | function transferFrom( 30 | bytes calldata assetData, 31 | address from, 32 | address to, 33 | uint256 amount 34 | ) external virtual; 35 | 36 | /// @dev Gets the proxy id associated with the proxy address. 37 | /// @return Proxy id. 38 | function getProxyId() external pure virtual returns (bytes4); 39 | } 40 | -------------------------------------------------------------------------------- /contracts/utils/0xUtils/IERC20Token.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Original work Copyright 2019 ZeroEx Intl. 5 | Modified work Copyright 2020 Rigo Intl. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | 19 | */ 20 | 21 | pragma solidity >=0.5.9 <0.9.0; 22 | 23 | abstract contract IERC20Token { 24 | // solhint-disable no-simple-event-func-name 25 | event Transfer(address indexed _from, address indexed _to, uint256 _value); 26 | 27 | event Approval(address indexed _owner, address indexed _spender, uint256 _value); 28 | 29 | /// @dev send `value` token to `to` from `msg.sender` 30 | /// @param _to The address of the recipient 31 | /// @param _value The amount of token to be transferred 32 | /// @return True if transfer was successful 33 | function transfer(address _to, uint256 _value) external virtual returns (bool); 34 | 35 | /// @dev send `value` token to `to` from `from` on the condition it is approved by `from` 36 | /// @param _from The address of the sender 37 | /// @param _to The address of the recipient 38 | /// @param _value The amount of token to be transferred 39 | /// @return True if transfer was successful 40 | function transferFrom( 41 | address _from, 42 | address _to, 43 | uint256 _value 44 | ) external virtual returns (bool); 45 | 46 | /// @dev `msg.sender` approves `_spender` to spend `_value` tokens 47 | /// @param _spender The address of the account able to transfer the tokens 48 | /// @param _value The amount of wei to be approved for transfer 49 | /// @return Always true if the call has enough gas to complete execution 50 | function approve(address _spender, uint256 _value) external virtual returns (bool); 51 | 52 | /// @dev Query total supply of token 53 | /// @return Total supply of token 54 | function totalSupply() external view virtual returns (uint256); 55 | 56 | /// @param _owner The address from which the balance will be retrieved 57 | /// @return Balance of owner 58 | function balanceOf(address _owner) external view virtual returns (uint256); 59 | 60 | /// @param _owner The address of the account owning tokens 61 | /// @param _spender The address of the account able to transfer the tokens 62 | /// @return Amount of remaining tokens allowed to spent 63 | function allowance(address _owner, address _spender) external view virtual returns (uint256); 64 | } 65 | -------------------------------------------------------------------------------- /contracts/utils/0xUtils/IEtherToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2019 ZeroEx Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.5.9 <0.9.0; 21 | 22 | import "./IERC20Token.sol"; 23 | 24 | abstract contract IEtherToken is IERC20Token { 25 | function deposit() public payable virtual; 26 | 27 | function withdraw(uint256 amount) public virtual; 28 | } 29 | -------------------------------------------------------------------------------- /contracts/utils/0xUtils/Ownable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | Copyright 2019 ZeroEx Intl. 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | See the License for the specific language governing permissions and 12 | limitations under the License. 13 | */ 14 | 15 | pragma solidity >=0.5.9 <0.9.0; 16 | 17 | import "./interfaces/IOwnable.sol"; 18 | 19 | abstract contract Ownable is IOwnable { 20 | /// @dev The owner of this contract. 21 | /// @return 0 The owner address. 22 | address public owner; 23 | 24 | constructor(address newOwner) { 25 | owner = newOwner; 26 | } 27 | 28 | modifier onlyOwner() { 29 | _assertSenderIsOwner(); 30 | _; 31 | } 32 | 33 | /// @dev Change the owner of this contract. 34 | /// @param newOwner New owner address. 35 | function transferOwnership(address newOwner) public override onlyOwner { 36 | require(newOwner != address(0), "INPUT_ADDRESS_NULL_ERROR"); 37 | owner = newOwner; 38 | emit OwnershipTransferred(msg.sender, newOwner); 39 | } 40 | 41 | function _assertSenderIsOwner() internal view { 42 | require(msg.sender == owner, "CALLER_NOT_OWNER_ERROR"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /contracts/utils/0xUtils/interfaces/IAuthorizable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | Copyright 2019 ZeroEx Intl. 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | See the License for the specific language governing permissions and 12 | limitations under the License. 13 | */ 14 | 15 | pragma solidity >=0.5.9 <0.9.0; 16 | 17 | abstract contract IAuthorizable { 18 | /// @dev Emitted when a new address is authorized. 19 | /// @param target Address of the authorized address. 20 | /// @param caller Address of the address that authorized the target. 21 | event AuthorizedAddressAdded(address indexed target, address indexed caller); 22 | 23 | /// @dev Emitted when a currently authorized address is unauthorized. 24 | /// @param target Address of the authorized address. 25 | /// @param caller Address of the address that authorized the target. 26 | event AuthorizedAddressRemoved(address indexed target, address indexed caller); 27 | 28 | /// @dev Authorizes an address. 29 | /// @param target Address to authorize. 30 | function addAuthorizedAddress(address target) external virtual; 31 | 32 | /// @dev Removes authorizion of an address. 33 | /// @param target Address to remove authorization from. 34 | function removeAuthorizedAddress(address target) external virtual; 35 | 36 | /// @dev Removes authorizion of an address. 37 | /// @param target Address to remove authorization from. 38 | /// @param index Index of target in authorities array. 39 | function removeAuthorizedAddressAtIndex(address target, uint256 index) external virtual; 40 | 41 | /// @dev Gets all authorized addresses. 42 | /// @return Array of authorized addresses. 43 | function getAuthorizedAddresses() external view virtual returns (address[] memory); 44 | } 45 | -------------------------------------------------------------------------------- /contracts/utils/0xUtils/interfaces/IOwnable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | Copyright 2019 ZeroEx Intl. 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | See the License for the specific language governing permissions and 12 | limitations under the License. 13 | */ 14 | 15 | pragma solidity >=0.5.9 <0.9.0; 16 | 17 | abstract contract IOwnable { 18 | /// @dev Emitted by Ownable when ownership is transferred. 19 | /// @param previousOwner The previous owner of the contract. 20 | /// @param newOwner The new owner of the contract. 21 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 22 | 23 | /// @dev Transfers ownership of the contract to a new address. 24 | /// @param newOwner The address that will become the owner. 25 | function transferOwnership(address newOwner) public virtual; 26 | } 27 | -------------------------------------------------------------------------------- /contracts/utils/exchanges/uniswap/v3-periphery/contracts/interfaces/IPeripheryImmutableState.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0 <0.9.0; 3 | 4 | /// @title Immutable state 5 | /// @notice Functions that return immutable state of the router 6 | interface IPeripheryImmutableState { 7 | /// @return Returns the address of the Uniswap V3 factory 8 | function factory() external view returns (address); 9 | 10 | /// @return Returns the address of WETH9 11 | function WETH9() external view returns (address); 12 | } 13 | -------------------------------------------------------------------------------- /contracts/utils/exchanges/uniswap/v3-periphery/contracts/interfaces/IPoolInitializer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5 <0.9.0; 3 | pragma abicoder v2; 4 | 5 | /// @title Creates and initializes V3 Pools 6 | /// @notice Provides a method for creating and initializing a pool, if necessary, for bundling with other methods that 7 | /// require the pool to exist. 8 | interface IPoolInitializer { 9 | /// @notice Creates a new pool if it does not exist, then initializes if not initialized 10 | /// @dev This method can be bundled with others via IMulticall for the first action (e.g. mint) performed against a pool 11 | /// @param token0 The contract address of token0 of the pool 12 | /// @param token1 The contract address of token1 of the pool 13 | /// @param fee The fee amount of the v3 pool for the specified token pair 14 | /// @param sqrtPriceX96 The initial square root price of the pool as a Q64.96 value 15 | /// @return pool Returns the pool address based on the pair of tokens and fee, will return the newly created pool address if necessary 16 | function createAndInitializePoolIfNecessary( 17 | address token0, 18 | address token1, 19 | uint24 fee, 20 | uint160 sqrtPriceX96 21 | ) external payable returns (address pool); 22 | } 23 | -------------------------------------------------------------------------------- /contracts/utils/exchanges/uniswap/v3-periphery/contracts/interfaces/external/IERC721.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | interface IERC721 { 5 | /// @notice Returns the owner of a given id. 6 | /// @param tokenId Number of the token id. 7 | /// @return owner Address of the token owner. 8 | function ownerOf(uint256 tokenId) external view returns (address owner); 9 | } 10 | -------------------------------------------------------------------------------- /contracts/utils/libSanitize/LibSanitize.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2017-2018 RigoBlock, Rigo Investment Sagl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.8.0 <0.9.0; 21 | 22 | /// @title Lib Sanitize - Sanitize strings in smart contracts. 23 | /// @author Gabriele Rigo - 24 | library LibSanitize { 25 | function assertIsValidCheck(string memory str) internal pure { 26 | bytes memory bStr = bytes(str); 27 | uint256 arrayLength = bStr.length; 28 | require(bStr[0] != bytes1(uint8(32)), "LIBSANITIZE_SPACE_AT_BEGINNING_ERROR"); 29 | require(bStr[arrayLength - 1] != bytes1(uint8(32)), "LIBSANITIZE_SPACE_AT_END_ERROR"); 30 | for (uint256 i = 0; i < arrayLength; i++) { 31 | if ( 32 | (bStr[i] < bytes1(uint8(48)) || 33 | bStr[i] > bytes1(uint8(122)) || 34 | (bStr[i] > bytes1(uint8(57)) && bStr[i] < bytes1(uint8(65))) || 35 | (bStr[i] > bytes1(uint8(90)) && bStr[i] < bytes1(uint8(97)))) && bStr[i] != bytes1(uint8(32)) 36 | ) revert("LIBSANITIZE_SPECIAL_CHARACTER_ERROR"); 37 | } 38 | } 39 | 40 | function assertIsLowercase(string memory str) internal pure { 41 | bytes memory bStr = bytes(str); 42 | uint256 arrayLength = bStr.length; 43 | for (uint256 i = 0; i < arrayLength; i++) { 44 | if ((bStr[i] >= bytes1(uint8(65))) && (bStr[i] <= bytes1(uint8(90)))) 45 | revert("LIBSANITIZE_LOWERCASE_CHARACTER_ERROR"); 46 | } 47 | } 48 | 49 | function assertIsUppercase(string memory str) internal pure { 50 | bytes memory bStr = bytes(str); 51 | uint256 arrayLength = bStr.length; 52 | for (uint256 i = 0; i < arrayLength; i++) { 53 | if ((bStr[i] >= bytes1(uint8(97))) && (bStr[i] <= bytes1(uint8(122)))) 54 | revert("LIBSANITIZE_UPPERCASE_CHARACTER_ERROR"); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /contracts/utils/owned/IOwnedUninitialized.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | /* 3 | 4 | Copyright 2022 Rigo Intl. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | */ 19 | 20 | pragma solidity >=0.7.0 <0.9.0; 21 | 22 | /// @title Rigoblock V3 Pool Interface - Allows interaction with the pool contract. 23 | /// @author Gabriele Rigo - 24 | // solhint-disable-next-line 25 | interface IOwnedUninitialized { 26 | /// @notice Emitted when new owner is set. 27 | /// @param old Address of the previous owner. 28 | /// @param current Address of the new owner. 29 | event NewOwner(address indexed old, address indexed current); 30 | 31 | /// @notice Allows current owner to set a new owner address. 32 | /// @dev Method restricted to owner. 33 | /// @param newOwner Address of the new owner. 34 | function setOwner(address newOwner) external; 35 | 36 | /// @notice Returns the address of the owner. 37 | /// @return Address of the owner. 38 | function owner() external view returns (address); 39 | } 40 | -------------------------------------------------------------------------------- /contracts/utils/owned/OwnedUninitialized.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache 2.0 2 | pragma solidity >=0.7.0 <0.9.0; 3 | 4 | import {IOwnedUninitialized} from "./IOwnedUninitialized.sol"; 5 | 6 | abstract contract OwnedUninitialized is IOwnedUninitialized { 7 | /// @inheritdoc IOwnedUninitialized 8 | address public override owner; 9 | 10 | modifier onlyOwner() { 11 | require(msg.sender == owner, "OWNED_CALLER_IS_NOT_OWNER_ERROR"); 12 | _; 13 | } 14 | 15 | /// @inheritdoc IOwnedUninitialized 16 | function setOwner(address newOwner) public override onlyOwner { 17 | require(newOwner != address(0)); 18 | address oldOWner = newOwner; 19 | owner = newOwner; 20 | emit NewOwner(oldOWner, newOwner); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = 'contracts' 3 | out = 'out' 4 | libs = ['node_modules', 'lib'] 5 | test = 'test' 6 | cache_path = 'cache_forge' 7 | optimizer_runs = 1_000_000 8 | auto_detect_solc = true -------------------------------------------------------------------------------- /remappings.txt: -------------------------------------------------------------------------------- 1 | forget-std/=lib/forget-std 2 | solmate/=lib/solmate 3 | permit2/=lib/permit2 4 | @uniswap/universal-router/=lib/universal-router/ 5 | @uniswap/v3-periphery/=lib/universal-router/lib/v3-periphery/ 6 | @uniswap/v4-periphery/=lib/universal-router/lib/v4-periphery/ 7 | @uniswap/v4-core/=lib/universal-router/lib/v4-periphery/lib/v4-core 8 | @openzeppelin-legacy/=lib/universal-router/lib/v4-periphery/lib/v4-core/lib/openzeppelin-contracts/ -------------------------------------------------------------------------------- /src/deploy/deploy_factories.ts: -------------------------------------------------------------------------------- 1 | import { DeployFunction } from "hardhat-deploy/types"; 2 | import { HardhatRuntimeEnvironment } from "hardhat/types"; 3 | 4 | const deploy: DeployFunction = async function ( 5 | hre: HardhatRuntimeEnvironment, 6 | ) { 7 | const { deployments, getNamedAccounts } = hre; 8 | const { deployer } = await getNamedAccounts(); 9 | const { deploy } = deployments; 10 | 11 | const authority = await deploy("Authority", { 12 | from: deployer, 13 | args: [deployer], 14 | log: true, 15 | deterministicDeployment: true, 16 | }); 17 | 18 | const registry = await deploy("PoolRegistry", { 19 | from: deployer, 20 | args: [ 21 | authority.address, 22 | deployer // Rigoblock Dao 23 | ], 24 | log: true, 25 | deterministicDeployment: true, 26 | }); 27 | 28 | const originalImplementationAddress = "0xeb0c08Ad44af89BcBB5Ed6dD28caD452311B8516" 29 | /*const proxyFactory =*/ await deploy("RigoblockPoolProxyFactory", { 30 | from: deployer, 31 | args: [ 32 | originalImplementationAddress, 33 | registry.address 34 | ], 35 | log: true, 36 | deterministicDeployment: true, 37 | }); 38 | 39 | // Notice: pool implementation requires deployed extensionsMap address (same on all chains) 40 | /*const extensionsMap = "0xeb0c08Ad44af89BcBB5Ed6dD28caD452311B8516" 41 | const weth = "0xeb0c08Ad44af89BcBB5Ed6dD28caD452311B8516" 42 | const poolImplementation = await deploy("SmartPool", { 43 | from: deployer, 44 | args: [authority.address, extensionsMap, weth], 45 | log: true, 46 | deterministicDeployment: true, 47 | }); 48 | 49 | const proxyFactoryInstance = await hre.ethers.getContractAt( 50 | "RigoblockPoolProxyFactory", 51 | proxyFactory.address 52 | ); 53 | const currentImplementation = await proxyFactoryInstance.implementation() 54 | if (currentImplementation !== poolImplementation.address) { 55 | await proxyFactoryInstance.setImplementation(poolImplementation.address) 56 | }*/ 57 | }; 58 | 59 | deploy.tags = ['factory', 'pool-deps', 'l2-suite', 'main-suite'] 60 | export default deploy; 61 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './utils/proxies' 2 | export * from './utils/constants' 3 | -------------------------------------------------------------------------------- /src/tasks/deploy_contracts.ts: -------------------------------------------------------------------------------- 1 | import "hardhat-deploy"; 2 | import "@nomiclabs/hardhat-ethers"; 3 | import { task } from "hardhat/config"; 4 | 5 | task("deploy-contracts", "Deploys and verifies Rigoblock contracts") 6 | .setAction(async (_, hre) => { 7 | console.log("Deploying contracts..."); 8 | await hre.run("deploy") 9 | 10 | console.log("Running local verification..."); 11 | await hre.run("local-verify") 12 | 13 | // Check if Sourcify is enabled (Unichain, for example, not supported by Sourcify yet) 14 | console.log("Running Sourcify verification..."); 15 | try { 16 | await hre.run("sourcify", { writeFailingMetadata: true }); 17 | console.log("Sourcify verification completed."); 18 | } catch (error) { 19 | console.error("Sourcify verification failed:", error.message); 20 | } 21 | await hre.run("sourcify") 22 | 23 | console.log("Verifying contracts on chain explorer..."); 24 | const deployments = await hre.deployments.all(); 25 | for (const [contractName, deployment] of Object.entries(deployments)) { 26 | const { address, args , metadata } = deployment; 27 | console.log(`Verifying ${contractName} at ${address}...`); 28 | 29 | try { 30 | let contractPath: string | undefined; 31 | if (metadata && typeof metadata === "string") { 32 | try { 33 | const parsedMetadata = JSON.parse(metadata); 34 | const sourcePath = parsedMetadata?.settings?.compilationTarget?.[0]; 35 | if (sourcePath) { 36 | contractPath = `${sourcePath}:${contractName}`; 37 | } 38 | } catch (parseError) { 39 | console.warn(`Failed to parse metadata for ${contractName}:`, parseError.message); 40 | } 41 | } 42 | 43 | // Run verification 44 | await hre.run("verify:verify", { 45 | address, 46 | constructorArguments: args || [], 47 | contract: contractPath, 48 | forceLicense: true, 49 | license: "Apache-2.0", 50 | }); 51 | console.log(`Successfully verified ${contractName} at ${address}`); 52 | } catch (error) { 53 | console.error(`Failed to verify ${contractName} at ${address}:`, error.message); 54 | } 55 | } 56 | }); 57 | 58 | export {} 59 | -------------------------------------------------------------------------------- /src/tasks/local_verify.ts: -------------------------------------------------------------------------------- 1 | import "hardhat-deploy"; 2 | import "@nomiclabs/hardhat-ethers"; 3 | import { task } from "hardhat/config"; 4 | import { loadSolc } from "../utils/solc"; 5 | 6 | task("local-verify", "Verifies that the local deployment files correspond to the on chain code") 7 | .setAction(async (_, hre) => { 8 | const allowedSourceKey = ['keccak256', 'content'] 9 | const deployedContracts = await hre.deployments.all() 10 | for (const contract of Object.keys(deployedContracts)) { 11 | const deployment = await hre.deployments.get(contract) 12 | const meta = JSON.parse(deployment.metadata!!) 13 | const solcjs = await loadSolc(meta.compiler.version) 14 | delete meta.compiler 15 | delete meta.output 16 | delete meta.version 17 | const sources = Object.values(meta.sources) 18 | for (const source of sources) { 19 | for (const key of Object.keys(source)) { 20 | if (allowedSourceKey.indexOf(key) < 0) 21 | delete source[key] 22 | } 23 | } 24 | meta.settings.outputSelection = {} 25 | const targets = Object.entries(meta.settings.compilationTarget) 26 | for (const [key, value] of targets) { 27 | meta.settings.outputSelection[key] = {} 28 | meta.settings.outputSelection[key][value as string] = [ 29 | 'evm.bytecode', 30 | 'evm.deployedBytecode', 31 | 'metadata' 32 | ]; 33 | } 34 | delete meta.settings.compilationTarget 35 | const compiled = solcjs.compile(JSON.stringify(meta)); 36 | const output = JSON.parse(compiled); 37 | for (const [key, value] of targets) { 38 | const compiledContract = output.contracts[key][value as string]; 39 | const onChainCode = await hre.ethers.provider.getCode(deployment.address) 40 | const onchainBytecodeHash = hre.ethers.utils.keccak256(onChainCode) 41 | const localBytecodeHash = hre.ethers.utils.keccak256(`0x${compiledContract.evm.deployedBytecode.object}`) 42 | const verifySuccess = onchainBytecodeHash === localBytecodeHash ? "SUCCESS" : "FAILURE" 43 | console.log(`Verification status for ${value}: ${verifySuccess}`) 44 | } 45 | } 46 | }); 47 | 48 | export { } 49 | -------------------------------------------------------------------------------- /src/tasks/show_codesize.ts: -------------------------------------------------------------------------------- 1 | import "hardhat-deploy"; 2 | import "@nomiclabs/hardhat-ethers"; 3 | import { task, types } from "hardhat/config"; 4 | import { loadSolc } from "../utils/solc"; 5 | 6 | task("codesize", "Displays the codesize of the contracts") 7 | .addParam("skipcompile", "should not compile before printing size", false, types.boolean, true) 8 | .addParam("contractname", "name of the contract", undefined, types.string, true) 9 | .setAction(async (taskArgs, hre) => { 10 | if (!taskArgs.skipcompile) { 11 | await hre.run("compile") 12 | } 13 | const contracts = await hre.artifacts.getAllFullyQualifiedNames() 14 | for (const contract of contracts) { 15 | const artifact = await hre.artifacts.readArtifact(contract) 16 | if (taskArgs.contractname && taskArgs.contractname !== artifact.contractName) continue 17 | console.log(artifact.contractName, Math.max(0, (artifact.deployedBytecode.length - 2) / 2), "bytes (limit is 24576)") 18 | } 19 | }); 20 | 21 | task("yulcode", "Outputs yul code for contracts") 22 | .addParam("contractname", "name of the contract", undefined, types.string, true) 23 | .setAction(async (taskArgs, hre) => { 24 | const contracts = await hre.artifacts.getAllFullyQualifiedNames() 25 | for (const contract of contracts) { 26 | if (taskArgs.contractname && !contract.endsWith(taskArgs.contractname)) continue 27 | const buildInfo = await hre.artifacts.getBuildInfo(contract) 28 | if (!buildInfo) return 29 | console.log({buildInfo}) 30 | buildInfo.input.settings.outputSelection['*']['*'].push("ir", "evm.assembly") 31 | const solcjs = await loadSolc(buildInfo.solcLongVersion) 32 | const compiled = solcjs.compile(JSON.stringify(buildInfo.input)) 33 | const output = JSON.parse(compiled); 34 | console.log(output.contracts[contract.split(":")[0]]) 35 | console.log(output.errors) 36 | } 37 | }); 38 | 39 | export { } 40 | -------------------------------------------------------------------------------- /src/utils/proxies.ts: -------------------------------------------------------------------------------- 1 | import { ethers, Contract } from "ethers" 2 | 3 | export const calculateProxyAddress = async (factory: Contract, singleton: string, inititalizer: string, nonce: number | string) => { 4 | const deploymentCode = ethers.utils.solidityPack(["bytes", "uint256"], [await factory.proxyCreationCode(), singleton]) 5 | const salt = ethers.utils.solidityKeccak256( 6 | ["bytes32", "uint256"], 7 | [ethers.utils.solidityKeccak256(["bytes"], [inititalizer]), nonce] 8 | ) 9 | return ethers.utils.getCreate2Address(factory.address, salt, ethers.utils.keccak256(deploymentCode)) 10 | } 11 | 12 | export const calculateProxyAddressWithCallback = async (factory: Contract, singleton: string, inititalizer: string, nonce: number | string, callback: string) => { 13 | const saltNonceWithCallback = ethers.utils.solidityKeccak256( 14 | ["uint256", "address"], 15 | [nonce, callback] 16 | ) 17 | return calculateProxyAddress(factory, singleton, inititalizer, saltNonceWithCallback) 18 | } 19 | -------------------------------------------------------------------------------- /src/utils/solc.ts: -------------------------------------------------------------------------------- 1 | import solc from "solc" 2 | 3 | const solcCache: Record = {} 4 | 5 | export const loadSolc = async (version: string): Promise => { 6 | return await new Promise((resolve, reject) => { 7 | if (solcCache[version] !== undefined) resolve(solcCache[version]) 8 | else solc.loadRemoteVersion(`v${version}`, (error: any, soljson: any) => { 9 | solcCache[version] = soljson 10 | return (error) ? reject(error) : resolve(soljson); 11 | }); 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /test/libraries/TestSafeTransferLib.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | import hre, { deployments, waffle, ethers } from "hardhat"; 3 | import "@nomiclabs/hardhat-ethers"; 4 | import { AddressZero } from "@ethersproject/constants"; 5 | import { parseEther } from "@ethersproject/units"; 6 | import { BigNumber, Contract } from "ethers"; 7 | 8 | describe("TestSafeTransferLib", async () => { 9 | const [ user1, user2 ] = waffle.provider.getWallets() 10 | 11 | const setupTests = deployments.createFixture(async () => { 12 | const TestSafeTransferLib = await hre.ethers.getContractFactory("TestSafeTransferLib") 13 | const testSafeTransferLib = await TestSafeTransferLib.deploy() 14 | return { 15 | testSafeTransferLib 16 | } 17 | }) 18 | 19 | describe("testForceApprove", async () => { 20 | it('should set approval of non-standard ERC20', async () => { 21 | const { testSafeTransferLib } = await setupTests() 22 | const amount = parseEther('1') 23 | await expect( 24 | testSafeTransferLib.testForceApprove(user2.address, amount) 25 | ).to.emit(testSafeTransferLib, 'Approval').withArgs(testSafeTransferLib.address, user2.address, amount) 26 | await expect( 27 | testSafeTransferLib.testForceApprove(user2.address, amount.div(2)) 28 | ).to.emit(testSafeTransferLib, 'Approval').withArgs(testSafeTransferLib.address, user2.address, amount.div(2)) 29 | }) 30 | }) 31 | }) 32 | -------------------------------------------------------------------------------- /test/shared/constants.ts: -------------------------------------------------------------------------------- 1 | import hre from 'hardhat' 2 | const { ethers } = hre 3 | 4 | // Router Helpers 5 | export const MAX_UINT = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' 6 | export const MAX_UINT128 = '0xffffffffffffffffffffffffffffffff' 7 | export const MAX_UINT160 = '0xffffffffffffffffffffffffffffffffffffffff' 8 | export const DEADLINE = 2000000000 9 | export const CONTRACT_BALANCE = '0x8000000000000000000000000000000000000000000000000000000000000000' 10 | export const OPEN_DELTA = 0 11 | export const ALREADY_PAID = 0 12 | export const ALICE_ADDRESS = '0x28c6c06298d514db089934071355e5743bf21d60' 13 | export const ETH_ADDRESS = ethers.constants.AddressZero 14 | export const ZERO_ADDRESS = ethers.constants.AddressZero 15 | export const ONE_PERCENT_BIPS = 100 16 | export const MSG_SENDER: string = '0x0000000000000000000000000000000000000001' 17 | export const ADDRESS_THIS: string = '0x0000000000000000000000000000000000000002' 18 | export const SOURCE_MSG_SENDER: boolean = true 19 | export const SOURCE_ROUTER: boolean = false 20 | 21 | // Constructor Params 22 | export const PERMIT2_ADDRESS = '0x000000000022D473030F116dDEE9F6B43aC78BA3' 23 | export const V2_FACTORY_MAINNET = '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f' 24 | export const V3_FACTORY_MAINNET = '0x1F98431c8aD98523631AE4a59f267346ea31F984' 25 | export const V3_INIT_CODE_HASH_MAINNET = '0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54' 26 | export const V2_INIT_CODE_HASH_MAINNET = '0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' 27 | export const V3_NFT_POSITION_MANAGER_MAINNET = '0xC36442b4a4522E871399CD717aBDD847Ab11FE88' 28 | export const V4_POSITION_DESCRIPTOR_ADDRESS = '0x0000000000000000000000000000000000000000' // TODO, deploy this in-line and use the proper address in posm's constructor 29 | export const WETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' -------------------------------------------------------------------------------- /test/staking/libs/TestCobbDouglas.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | import hre, { deployments, waffle, ethers } from "hardhat"; 3 | import "@nomiclabs/hardhat-ethers"; 4 | 5 | describe("TestCobbDouglas", async () => { 6 | const [ user1, user2 ] = waffle.provider.getWallets() 7 | 8 | const setupTests = deployments.createFixture(async () => { 9 | const TestCobbDouglas = await hre.ethers.getContractFactory("TestCobbDouglas") 10 | const testCobbDouglas = await TestCobbDouglas.deploy() 11 | return { 12 | testCobbDouglas 13 | } 14 | }) 15 | 16 | describe("getCobbDouglasReward", async () => { 17 | it('should return 0 with 0 fee ratio or 0 stake ratio', async () => { 18 | const { testCobbDouglas } = await setupTests() 19 | let reward 20 | reward = await testCobbDouglas.getCobbDouglasReward( 21 | 100, 22 | 10, 23 | 100, 24 | 20, 25 | 200, 26 | 2, 27 | 3 28 | ) 29 | expect(reward).to.be.not.eq(0) 30 | reward = await testCobbDouglas.getCobbDouglasReward( 31 | 100, 32 | 0, 33 | 100, 34 | 20, 35 | 200, 36 | 2, 37 | 3 38 | ) 39 | expect(reward).to.be.deep.eq(0) 40 | reward = await testCobbDouglas.getCobbDouglasReward( 41 | 100, 42 | 10, 43 | 100, 44 | 0, 45 | 200, 46 | 2, 47 | 3 48 | ) 49 | expect(reward).to.be.deep.eq(0) 50 | }) 51 | }) 52 | }) 53 | -------------------------------------------------------------------------------- /test/staking/libs/TestSafeDowncast.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | import hre, { deployments, waffle, ethers } from "hardhat"; 3 | import "@nomiclabs/hardhat-ethers"; 4 | import { AddressZero } from "@ethersproject/constants"; 5 | import { parseEther } from "@ethersproject/units"; 6 | import { BigNumber, Contract } from "ethers"; 7 | 8 | describe("TestSafeDowncast", async () => { 9 | const [ user1, user2 ] = waffle.provider.getWallets() 10 | 11 | const setupTests = deployments.createFixture(async () => { 12 | const TestSafeDowncast = await hre.ethers.getContractFactory("TestLibSafeDowncast") 13 | const testSafeDowncast = await TestSafeDowncast.deploy() 14 | return { 15 | testSafeDowncast 16 | } 17 | }) 18 | 19 | describe("downcastToUint96", async () => { 20 | it('should revert when bigger than uint96', async () => { 21 | const { testSafeDowncast } = await setupTests() 22 | const uint100 = BigNumber.from('2').pow(100).sub(1) 23 | await expect(testSafeDowncast.downcastToUint96(uint100)) 24 | .to.be.revertedWith("VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT96") 25 | }) 26 | }) 27 | 28 | describe("downcastToUint64", async () => { 29 | it('should revert when bigger than uint64', async () => { 30 | const { testSafeDowncast } = await setupTests() 31 | const uint80 = BigNumber.from('2').pow(80).sub(1) 32 | await expect(testSafeDowncast.downcastToUint64(uint80)) 33 | .to.be.revertedWith("VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT64") 34 | }) 35 | }) 36 | }) 37 | -------------------------------------------------------------------------------- /test/utils/eip712sig.ts: -------------------------------------------------------------------------------- 1 | import {waffle} from "hardhat" 2 | import { VoteType } from "./utils" 3 | 4 | export interface SigOpts { 5 | governance?: string; 6 | proposalId?: number; 7 | voteType?: VoteType; 8 | } 9 | 10 | export async function signEip712Message(opts: SigOpts) { 11 | const domain = { 12 | name: 'Rigoblock Governance', 13 | version: '1.0.0', 14 | chainId: 31337, 15 | verifyingContract: opts.governance 16 | } 17 | const types = { 18 | Vote: [ 19 | { name: 'proposalId', type: 'uint256' }, 20 | { name: 'voteType', type: 'uint8' } 21 | ] 22 | } 23 | const value = { 24 | proposalId: opts.proposalId, 25 | voteType: opts.voteType 26 | } 27 | const signer = waffle.provider.getSigner() 28 | const signature = await signer._signTypedData(domain, types, value) 29 | return { 30 | "signature": signature, 31 | "domain": domain, 32 | "types": types, 33 | "value": value 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test/utils/path.ts: -------------------------------------------------------------------------------- 1 | // we also add null fee amount for testing 2 | const FEE_SIZE = 3 3 | 4 | export function encodePath(path: string[], fees: FeeAmount[]): string { 5 | if (path.length != fees.length + 1) { 6 | throw new Error('path/fee lengths do not match') 7 | } 8 | 9 | let encoded = '0x' 10 | for (let i = 0; i < fees.length; i++) { 11 | // 20 byte encoding of the address 12 | encoded += path[i].slice(2) 13 | // 3 byte encoding of the fee 14 | encoded += fees[i].toString(16).padStart(2 * FEE_SIZE, '0') 15 | } 16 | // encode the final token 17 | encoded += path[path.length - 1].slice(2) 18 | 19 | return encoded.toLowerCase() 20 | } 21 | 22 | export enum FeeAmount { 23 | LOW = 500, 24 | MEDIUM = 3000, 25 | HIGH = 10000 26 | } 27 | 28 | export const encodeMultihopExactInPath = (poolKeys: any[], currencyIn: string): any[] => { 29 | let pathKeys: { intermediateCurrency: any; fee: any; tickSpacing: any; hooks: any; hookData: string; }[] = [] 30 | for (let i = 0; i < poolKeys.length; i++) { 31 | let currencyOut = currencyIn == poolKeys[i].currency0 ? poolKeys[i].currency1 : poolKeys[i].currency0 32 | let pathKey = { 33 | intermediateCurrency: currencyOut, 34 | fee: poolKeys[i].fee, 35 | tickSpacing: poolKeys[i].tickSpacing, 36 | hooks: poolKeys[i].hooks, 37 | hookData: '0x', 38 | } 39 | pathKeys.push(pathKey) 40 | currencyIn = currencyOut 41 | } 42 | return pathKeys 43 | } 44 | 45 | export const encodeMultihopExactOutPath = (poolKeys: any[], currencyOut: string): any[] => { 46 | let pathKeys = [] 47 | for (let i = poolKeys.length; i > 0; i--) { 48 | let currencyIn = currencyOut == poolKeys[i - 1].currency0 ? poolKeys[i - 1].currency1 : poolKeys[i - 1].currency0 49 | let pathKey = { 50 | intermediateCurrency: currencyIn, 51 | fee: poolKeys[i - 1].fee, 52 | tickSpacing: poolKeys[i - 1].tickSpacing, 53 | hooks: poolKeys[i - 1].hooks, 54 | hookData: '0x', 55 | } 56 | // unshift pushes to the beginning of the array 57 | pathKeys.unshift(pathKey) 58 | currencyOut = currencyIn 59 | } 60 | return pathKeys 61 | } 62 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, 4 | "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, 5 | "lib": ["ES2015"], 6 | "allowJs": false /* Allow javascript files to be compiled. */, 7 | "declaration": true /* Generates corresponding '.d.ts' file. */, 8 | "sourceMap": false /* Generates corresponding '.map' file. */, 9 | "outDir": "./dist" /* Redirect output structure to the directory. */, 10 | "strict": true /* Enable all strict type-checking options. */, 11 | "noUnusedParameters": true /* Report errors on unused parameters. */, 12 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, 13 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, 14 | "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, 15 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 16 | "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, 17 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, 18 | "resolveJsonModule": true 19 | }, 20 | "exclude": ["dist", "node_modules"], 21 | "include": ["./src/index.ts", "./types"] 22 | } 23 | -------------------------------------------------------------------------------- /types/solc.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'solc'; 2 | --------------------------------------------------------------------------------