├── contracts ├── amm │ ├── README.md │ ├── interfaces │ │ ├── IUniswapV2Callee.sol │ │ ├── IWETH.sol │ │ ├── IUniswapV2Factory.sol │ │ ├── IERC20.sol │ │ ├── IUniswapV2ERC20.sol │ │ ├── IUniswapV2Router02.sol │ │ └── IUniswapV2Pair.sol │ ├── libraries │ │ ├── SafeMath.sol │ │ ├── UQ112x112.sol │ │ ├── Math.sol │ │ └── TransferHelper.sol │ ├── UniswapV2Factory.sol │ └── UniswapV2ERC20.sol ├── interfaces │ ├── ITriBar.sol │ ├── IWETH.sol │ ├── IAllowlist.sol │ ├── IRewarder.sol │ ├── IFlashLoanReceiver.sol │ ├── IMasterChefV2.sol │ ├── IMasterChef.sol │ ├── IGUniPool.sol │ ├── IGUniRouter.sol │ ├── ISwap.sol │ └── IMetaSwap.sol ├── rewards │ ├── README.md │ └── TriBar.sol ├── governance │ ├── README.md │ ├── Hodl.sol │ ├── Vester.sol │ └── FeeCollector.sol ├── mocks │ ├── TriMakerExploitMock.sol │ ├── UsdcMakerExploitMock.sol │ ├── ERC20Mock.sol │ ├── TestTokenMock.sol │ ├── StableLpMakerExploitMock.sol │ ├── StableLpMakerExploitMockV2.sol │ ├── StableLpMakerExploitMockV3.sol │ ├── EscrowMock.sol │ └── RewarderMock.sol ├── stableswap │ ├── OwnerPausableUpgradeable.sol │ ├── MathUtils.sol │ └── LPToken.sol ├── multicall │ └── Multicall.sol ├── weth │ ├── wturbo.sol │ ├── weth.sol │ └── ConfigurableWETH9.sol ├── libraries │ ├── BoringMath.sol │ └── SignedSafeMath.sol └── vaults │ └── UniswapV3Helpers.sol ├── deployments ├── .gitkeep ├── 1313161587.json ├── 1313161554.json ├── 1313161555.json ├── 1313161567.json ├── 1313161573.json └── 1313161585.json ├── .gitattributes ├── .czrc ├── .commitlintrc.yaml ├── rewarderTokensPerBlockConfig.sample.json ├── .lintstagedrc ├── complexNRewarderTokensPerBlockConfig.sample.json ├── allocationConfig.sample.json ├── .yarnrc.yml ├── .env.example ├── .solhintignore ├── .prettierrc.yaml ├── verify └── argumentsNRewarder.js ├── newComplexNRewarderConfig.sample.json ├── .eslintignore ├── .editorconfig ├── tasks ├── accounts.ts ├── clean.ts └── generate.ts ├── test ├── time.ts ├── weth │ └── weth.test.ts ├── governance │ ├── vester.test.ts │ ├── hodl.test.ts │ └── FeeCollector.test.ts └── rewards │ └── tribar.test.ts ├── newRewarderConfig.sample.json ├── .gitignore ├── .solhint.json ├── .prettierignore ├── .eslintrc.yaml ├── tsconfig.json ├── .solcover.js ├── .github └── workflows │ └── test.yml ├── scripts ├── verify │ ├── xtri.ts │ └── rewards.ts ├── ops │ ├── updateTriPerBlock.ts │ ├── claimVestedTokens.ts │ ├── convertFees.ts │ ├── updateStableLpMakerAddress.ts │ ├── setBridge.ts │ ├── updateDoubleRewardRate.ts │ ├── transferOwnership.ts │ ├── transferMasterChefOwnership.ts │ ├── changeTriPerBlock.ts │ ├── setFeeToSetter.ts │ ├── setFeeTo.ts │ ├── updateAllocPoint.ts │ ├── updateV2AllocPoint.ts │ ├── setRewarders.ts │ ├── checkBalance.ts │ ├── set3PoolFeeAddress.ts │ ├── pointStablePoolsToStableLPMakerV2.ts │ ├── addPool.ts │ ├── addPoolChefV2.ts │ ├── proposerUpdateTriPerBlock.ts │ ├── setMultipleBridges.ts │ ├── proposerRewarderTokensPerBlock.ts │ ├── proposerSetAllocation.ts │ └── proposerComplexNRewarderTokensPerBlock.ts ├── weth.ts ├── multicall.ts ├── vaults │ ├── uniswapV3Helpers.ts │ └── guniRouter.ts ├── turbo │ ├── 00_wturbo.ts │ ├── mocks │ │ ├── mockMock.ts │ │ ├── mockTri.ts │ │ └── mockUSDC.ts │ ├── ops │ │ ├── amm_setFeeTo.ts │ │ └── amm_setFeeToSetter.ts │ ├── 01_amm.ts │ └── 02_fee_collector.ts ├── doubleRewards.ts ├── manageTreasury │ └── sendFunds.ts ├── stableswap │ └── setAdminFees.ts ├── amm.ts ├── deployStableTRIStaking.ts ├── rewards.ts ├── xtri.ts ├── vesting.ts ├── nRewards.ts ├── setup3PoolAdminFee.ts ├── deployUsdcMaker.ts ├── rewards │ ├── deployStableLPMaker.ts │ └── deployStableLPMakerV2.ts ├── externalRewardPoolChefV2.ts └── revesting.ts └── README.md /contracts/amm/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /deployments/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity -------------------------------------------------------------------------------- /.czrc: -------------------------------------------------------------------------------- 1 | { 2 | "path": "cz-conventional-changelog" 3 | } 4 | -------------------------------------------------------------------------------- /.commitlintrc.yaml: -------------------------------------------------------------------------------- 1 | extends: 2 | - "@commitlint/config-conventional" 3 | -------------------------------------------------------------------------------- /rewarderTokensPerBlockConfig.sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "Rewarder": "address", 3 | "TokensPerBlock": "number" 4 | } 5 | -------------------------------------------------------------------------------- /.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "*.{js,json,md,sol,ts}": [ 3 | "prettier --config ./.prettierrc.yaml --write" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /complexNRewarderTokensPerBlockConfig.sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "Rewarder": "address", 3 | "TokensPerBlock": ["number", "number", "number"] 4 | } 5 | -------------------------------------------------------------------------------- /allocationConfig.sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "PoolId": "number", 3 | "Allocation": "number", 4 | "Rewarder": "address", 5 | "LpToken": "address" 6 | } 7 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | compressionLevel: mixed 2 | 3 | enableGlobalCache: false 4 | 5 | nodeLinker: node-modules 6 | 7 | yarnPath: .yarn/releases/yarn-3.1.0.cjs 8 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | INFURA_API_KEY=test 2 | AURORA_API_KEY=test 3 | ETHERSCAN_API_KEY=test 4 | MNEMONIC="test test test test test test test test test test test junk" 5 | -------------------------------------------------------------------------------- /contracts/interfaces/ITriBar.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: AGPL-3.0-only 2 | pragma solidity 0.7.6; 3 | 4 | interface ITriBar { 5 | function leave(uint256 xTriAmount) external; 6 | } 7 | -------------------------------------------------------------------------------- /.solhintignore: -------------------------------------------------------------------------------- 1 | # directories 2 | artifacts/ 3 | node_modules/ 4 | contracts/amm/ 5 | contracts/libraries/ 6 | contracts/multicall/ 7 | contracts/stableswap/ 8 | contracts/weth/ 9 | contracts/mocks/TestSwapReturnValues.sol 10 | contracts/vaults/vendor -------------------------------------------------------------------------------- /.prettierrc.yaml: -------------------------------------------------------------------------------- 1 | arrowParens: avoid 2 | bracketSpacing: true 3 | endOfLine: auto 4 | printWidth: 120 5 | singleQuote: false 6 | tabWidth: 2 7 | trailingComma: all 8 | 9 | overrides: 10 | - files: "*.sol" 11 | options: 12 | tabWidth: 4 13 | -------------------------------------------------------------------------------- /contracts/amm/interfaces/IUniswapV2Callee.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | interface IUniswapV2Callee { 6 | function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external; 7 | } 8 | -------------------------------------------------------------------------------- /verify/argumentsNRewarder.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | ["0x8bec47865ade3b172a928df8f990bc7f2a3b9f79", "0xC42C30aC6Cc15faC9bD938618BcaA1a1FaE8501d"], 3 | "0xd1654a7713617d41A8C9530Fb9B948d00e162194", 4 | ["0", "0"], 5 | "0x3838956710bcc9D122Dd23863a0549ca8D5675D6", 6 | ]; 7 | -------------------------------------------------------------------------------- /deployments/1313161587.json: -------------------------------------------------------------------------------- 1 | { 2 | "factory": "0xB7B4802D9Dcf4eE7414b39556eB73683992Ad003", 3 | "router": "0x1360f83a9348fBa26eD6C44b9F9874e8c42BC287", 4 | "weth": "0xA22d6bD9789283b6AaA57808d5875B7B9f0fD813", 5 | "multicall": "0xD8A9A3Ff4d76618ddBbEcfbaff4ACEe26cf316cF" 6 | } 7 | -------------------------------------------------------------------------------- /contracts/rewards/README.md: -------------------------------------------------------------------------------- 1 | ## Notes: 2 | 3 | Using the rewards contracts from SushiSwap 4 | 5 | ### Masterchef 6 | 7 | 1. Have removed migrator and devaddr functions/variables 8 | 2. Removed bonusMultiplier 9 | 3. Enabled the ability to change `sushiPerBlock` to the owner 10 | -------------------------------------------------------------------------------- /contracts/amm/interfaces/IWETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | interface IWETH { 6 | function deposit() external payable; 7 | function transfer(address to, uint value) external returns (bool); 8 | function withdraw(uint) external; 9 | } -------------------------------------------------------------------------------- /newComplexNRewarderConfig.sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "LPToken": "address", 3 | "isComplexNRewarder": "true", 4 | "RewardTokens": ["address", "address", "address"], 5 | "RewarderPriceLPs": ["string: https://www.coingecko.com/en/coins/trisolaris -> CMD+F for 'API id' OR address", "..."] 6 | } 7 | -------------------------------------------------------------------------------- /contracts/interfaces/IWETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity 0.8.4; 3 | 4 | interface IWETH { 5 | function deposit() external payable; 6 | 7 | function transfer(address to, uint256 value) external returns (bool); 8 | 9 | function withdraw(uint256) external; 10 | } 11 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # directories 2 | .yarn/ 3 | artifacts/ 4 | build/ 5 | cache/ 6 | coverage/ 7 | dist/ 8 | lib/ 9 | node_modules/ 10 | typechain/ 11 | 12 | # files 13 | *.env 14 | *.log 15 | *.tsbuildinfo 16 | .pnp.* 17 | .solcover.js 18 | coverage.json 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # All files 7 | [*] 8 | charset = utf-8 9 | end_of_line = lf 10 | indent_size = 2 11 | indent_style = space 12 | insert_final_newline = true 13 | trim_trailing_whitespace = true 14 | 15 | [*.sol] 16 | indent_size = 4 17 | -------------------------------------------------------------------------------- /deployments/1313161554.json: -------------------------------------------------------------------------------- 1 | { 2 | "factory": "0xc66F594268041dB60507F00703b152492fb176E7", 3 | "router": "0x2CB45Edb4517d5947aFdE3BEAbF95A582506858B", 4 | "weth": "0xC9BdeEd33CD01541e1eeD10f90519d2C06Fe3feB", 5 | "initCodeHash": "0x754e1d90e536e4c1df81b7f030f47b4ca80c87120e145c294f098c83a6cb5ace", 6 | "multicall": "0x49eb1F160e167aa7bA96BdD88B6C1f2ffda5212A" 7 | } 8 | -------------------------------------------------------------------------------- /deployments/1313161555.json: -------------------------------------------------------------------------------- 1 | { 2 | "factory": "0xB7B4802D9Dcf4eE7414b39556eB73683992Ad003", 3 | "router": "0x1360f83a9348fBa26eD6C44b9F9874e8c42BC287", 4 | "weth": "0xA22d6bD9789283b6AaA57808d5875B7B9f0fD813", 5 | "initCodeHash": "0x754e1d90e536e4c1df81b7f030f47b4ca80c87120e145c294f098c83a6cb5ace", 6 | "multicall": "0xD8A9A3Ff4d76618ddBbEcfbaff4ACEe26cf316cF" 7 | } 8 | -------------------------------------------------------------------------------- /deployments/1313161567.json: -------------------------------------------------------------------------------- 1 | { 2 | "factory": "0xf0BE0075F8De10044a7115FdCf7feC3afB3B8FE0", 3 | "router": "0x317f7714F49efCFdBF150640cf9E73C136676c0c", 4 | "weth": "0x21Cc007d2b777BBaB55d51e62F5C3F31DEaa7E5d", 5 | "initCodeHash": "0x754e1d90e536e4c1df81b7f030f47b4ca80c87120e145c294f098c83a6cb5ace", 6 | "multicall": "0x5FE8fF8c5Ae435f0EB613B063C684FE10099BFEa" 7 | } 8 | -------------------------------------------------------------------------------- /deployments/1313161573.json: -------------------------------------------------------------------------------- 1 | { 2 | "factory": "0xB7B4802D9Dcf4eE7414b39556eB73683992Ad003", 3 | "router": "0x1360f83a9348fBa26eD6C44b9F9874e8c42BC287", 4 | "weth": "0xA22d6bD9789283b6AaA57808d5875B7B9f0fD813", 5 | "initCodeHash": "0x754e1d90e536e4c1df81b7f030f47b4ca80c87120e145c294f098c83a6cb5ace", 6 | "multicall": "0xD8A9A3Ff4d76618ddBbEcfbaff4ACEe26cf316cF" 7 | } 8 | -------------------------------------------------------------------------------- /deployments/1313161585.json: -------------------------------------------------------------------------------- 1 | { 2 | "factory": "0x1360f83a9348fBa26eD6C44b9F9874e8c42BC287", 3 | "router": "0xD8A9A3Ff4d76618ddBbEcfbaff4ACEe26cf316cF", 4 | "weth": "0xB7B4802D9Dcf4eE7414b39556eB73683992Ad003", 5 | "initCodeHash": "0x754e1d90e536e4c1df81b7f030f47b4ca80c87120e145c294f098c83a6cb5ace", 6 | "multicall": "0x55404F107DEaf15ff9a6c744F0D820a8A9B31Ba2" 7 | } 8 | -------------------------------------------------------------------------------- /tasks/accounts.ts: -------------------------------------------------------------------------------- 1 | import { Signer } from "@ethersproject/abstract-signer"; 2 | import { task } from "hardhat/config"; 3 | 4 | task("accounts", "Prints the list of accounts", async (_taskArgs, hre) => { 5 | const accounts: Signer[] = await hre.ethers.getSigners(); 6 | 7 | for (const account of accounts) { 8 | console.log(await account.getAddress()); 9 | } 10 | }); 11 | -------------------------------------------------------------------------------- /tasks/clean.ts: -------------------------------------------------------------------------------- 1 | import fsExtra from "fs-extra"; 2 | import { TASK_CLEAN } from "hardhat/builtin-tasks/task-names"; 3 | import { task } from "hardhat/config"; 4 | 5 | task(TASK_CLEAN, "Overrides the standard clean task", async function (_taskArgs, _hre, runSuper) { 6 | await fsExtra.remove("./coverage"); 7 | await fsExtra.remove("./coverage.json"); 8 | await runSuper(); 9 | }); 10 | -------------------------------------------------------------------------------- /test/time.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "hardhat"; 2 | 3 | export async function advanceBlock(): Promise { 4 | return ethers.provider.send("evm_mine", []); 5 | } 6 | 7 | // eslint-disable-next-line 8 | export async function advanceBlockTo(blockNumber: any): Promise { 9 | for (let i = await ethers.provider.getBlockNumber(); i < blockNumber; i++) { 10 | await advanceBlock(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /contracts/governance/README.md: -------------------------------------------------------------------------------- 1 | ## Notes: 2 | 3 | Using the governance contracts from Uniswap 4 | 5 | ### Vesting 6 | 7 | 1. Contract is the same 8 | 9 | ### Tri -> Uni 10 | 11 | 1. Using this governance token instead of sushi because this token cannot double vote. 12 | 2. We have removed the minting limits from the minting contract. 13 | 3. The minter will be assigned to be an LP staking contract like Masterchef 14 | -------------------------------------------------------------------------------- /contracts/interfaces/IAllowlist.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | 5 | interface IAllowlist { 6 | function getPoolAccountLimit(address poolAddress) external view returns (uint256); 7 | 8 | function getPoolCap(address poolAddress) external view returns (uint256); 9 | 10 | function verifyAddress(address account, bytes32[] calldata merkleProof) external returns (bool); 11 | } 12 | -------------------------------------------------------------------------------- /tasks/generate.ts: -------------------------------------------------------------------------------- 1 | import { Wallet, utils } from "ethers"; 2 | import { task } from "hardhat/config"; 3 | 4 | task("generate", "Generate a mnemonic phrase", async (_taskArgs, _hre) => { 5 | const wallet = Wallet.fromMnemonic(utils.entropyToMnemonic(utils.randomBytes(32))); 6 | 7 | console.log("wallet.address:", wallet.address); 8 | console.log("wallet.mnemonic.phrase:", wallet.mnemonic.phrase); 9 | console.log("wallet.privateKey:", wallet.privateKey); 10 | }); 11 | -------------------------------------------------------------------------------- /newRewarderConfig.sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "LPToken": "address", 3 | "isStablePool": "`true` if pool will appear on https://www.trisolaris.io/#/pool/stable, otherwise delete this key", 4 | "RewardToken": "delete if no additional reward token or address", 5 | "CoingeckoRewarderTokenName": "delete if using RewarderPriceLP or string: https://www.coingecko.com/en/coins/trisolaris -> CMD+F for `API id", 6 | "RewarderPriceLP": "delete if using CoingeckoRewarderTokenName or address" 7 | } 8 | -------------------------------------------------------------------------------- /contracts/mocks/TriMakerExploitMock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import "../rewards/TriMaker.sol"; 6 | 7 | contract TriMakerExploitMock { 8 | TriMaker public immutable triMaker; 9 | 10 | constructor(address _triMaker) public { 11 | triMaker = TriMaker(_triMaker); 12 | } 13 | 14 | function convert(address token0, address token1) external { 15 | triMaker.convert(token0, token1); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /contracts/mocks/UsdcMakerExploitMock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import "../rewards/UsdcMaker.sol"; 6 | 7 | contract UsdcMakerExploitMock { 8 | UsdcMaker public immutable usdcMaker; 9 | 10 | constructor(address _usdcMaker) public { 11 | usdcMaker = UsdcMaker(_usdcMaker); 12 | } 13 | 14 | function convert(address token0, address token1) external { 15 | usdcMaker.convert(token0, token1); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # directories 2 | .coverage_artifacts/ 3 | .coverage_cache/ 4 | .coverage_contracts/ 5 | .yarn/* 6 | !.yarn/patches 7 | !.yarn/releases 8 | !.yarn/plugins 9 | !.yarn/sdks 10 | !.yarn/versions 11 | artifacts/ 12 | build/ 13 | cache/ 14 | coverage/ 15 | dist/ 16 | lib/ 17 | node_modules/ 18 | typechain/ 19 | 20 | # files 21 | *.env 22 | *.log 23 | *.tsbuildinfo 24 | coverage.json 25 | npm-debug.log* 26 | yarn-debug.log* 27 | yarn-error.log* 28 | *.DS_Store 29 | 30 | deployments/31337.json 31 | -------------------------------------------------------------------------------- /contracts/interfaces/IRewarder.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 5 | 6 | interface IRewarder { 7 | function onTriReward( 8 | uint256 pid, 9 | address user, 10 | address recipient, 11 | uint256 triAmount, 12 | uint256 newLpAmount 13 | ) external; 14 | 15 | function pendingTokens( 16 | uint256 pid, 17 | address user, 18 | uint256 triAmount 19 | ) external view returns (IERC20[] memory, uint256[] memory); 20 | } 21 | -------------------------------------------------------------------------------- /contracts/mocks/ERC20Mock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 6 | 7 | contract ERC20Mock is ERC20 { 8 | constructor( 9 | string memory name, 10 | string memory symbol, 11 | uint8 decimals, 12 | uint256 supply 13 | ) public ERC20(name, symbol) { 14 | _setupDecimals(decimals); 15 | _mint(msg.sender, supply); 16 | } 17 | 18 | function burn(address account, uint256 amount) public virtual { 19 | _burn(account, amount); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:recommended", 3 | "plugins": ["prettier"], 4 | "rules": { 5 | "code-complexity": ["error", 10], 6 | "compiler-version": ["error", ">=0.6.12"], 7 | "const-name-snakecase": "off", 8 | "constructor-syntax": "error", 9 | "func-visibility": ["error", { "ignoreConstructors": true }], 10 | "max-line-length": ["error", 120], 11 | "not-rely-on-time": "off", 12 | "prettier/prettier": [ 13 | "error", 14 | { 15 | "endOfLine": "auto" 16 | } 17 | ], 18 | "reason-string": ["warn", { "maxLength": 64 }] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /contracts/mocks/TestTokenMock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 6 | 7 | contract TestTokenMock is ERC20 { 8 | constructor( 9 | string memory name, 10 | string memory symbol, 11 | uint8 decimals, 12 | uint256 supply 13 | ) public ERC20(name, symbol) { 14 | _setupDecimals(decimals); 15 | _mint(msg.sender, supply); 16 | } 17 | 18 | function burn(address account, uint256 amount) public virtual { 19 | _burn(account, amount); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # directories 2 | .yarn/ 3 | artifacts/ 4 | build/ 5 | cache/ 6 | coverage/ 7 | dist/ 8 | lib/ 9 | node_modules/ 10 | typechain/ 11 | contracts/amm/ 12 | contracts/libraries/ 13 | contracts/multicall/ 14 | contracts/stableswap/ 15 | contracts/weth/ 16 | 17 | # files 18 | *.env 19 | *.log 20 | *.tsbuildinfo 21 | .pnp.* 22 | coverage.json 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | rewarderConfigs.json 27 | newRewarderConfig.json 28 | newRewarderConfig.sample.json 29 | allocationConfig.json 30 | allocationConfig.sample.json 31 | rewarderTokensPerBlockConfig.json 32 | rewarderTokensPerBlockConfig.sample.json -------------------------------------------------------------------------------- /contracts/mocks/StableLpMakerExploitMock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | pragma experimental ABIEncoderV2; 5 | 6 | import "../rewards/StableLPMaker.sol"; 7 | 8 | contract StableLpMakerExploitMock { 9 | StableLPMaker public immutable stableLpMaker; 10 | 11 | constructor(address _stableLpMaker) public { 12 | stableLpMaker = StableLPMaker(_stableLpMaker); 13 | } 14 | 15 | function convertStables( 16 | // solhint-disable-next-line no-unused-vars 17 | address swap // Stableswap Pool 18 | ) external { 19 | stableLpMaker.convertStables(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /contracts/interfaces/IFlashLoanReceiver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: AGPL-3.0-only 2 | 3 | pragma solidity 0.6.12; 4 | 5 | /** 6 | * @title IFlashLoanReceiver interface 7 | * @notice Interface for the Saddle fee IFlashLoanReceiver. Modified from Aave's IFlashLoanReceiver interface. 8 | * @author Aave 9 | * @dev implement this interface to develop a flashloan-compatible flashLoanReceiver contract 10 | **/ 11 | interface IFlashLoanReceiver { 12 | function executeOperation( 13 | address pool, 14 | address token, 15 | uint256 amount, 16 | uint256 fee, 17 | bytes calldata params 18 | ) external; 19 | } 20 | -------------------------------------------------------------------------------- /.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | extends: 2 | - "eslint:recommended" 3 | - "plugin:@typescript-eslint/eslint-recommended" 4 | - "plugin:@typescript-eslint/recommended" 5 | - "prettier" 6 | parser: "@typescript-eslint/parser" 7 | parserOptions: 8 | project: "tsconfig.json" 9 | plugins: 10 | - "@typescript-eslint" 11 | root: true 12 | env: 13 | node: true 14 | rules: 15 | "@typescript-eslint/no-floating-promises": 16 | - error 17 | - ignoreIIFE: true 18 | ignoreVoid: true 19 | "@typescript-eslint/no-inferrable-types": "off" 20 | "@typescript-eslint/no-unused-vars": 21 | - error 22 | - argsIgnorePattern: "_" 23 | varsIgnorePattern: "_" 24 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "forceConsistentCasingInFileNames": true, 5 | "lib": ["es6"], 6 | "module": "commonjs", 7 | "moduleResolution": "node", 8 | "noImplicitAny": true, 9 | "outDir": "dist", 10 | "resolveJsonModule": true, 11 | "sourceMap": true, 12 | "strict": true, 13 | "target": "es6" 14 | }, 15 | "exclude": ["node_modules"], 16 | "files": ["./hardhat.config.ts"], 17 | "include": [ 18 | "tasks/**/*.ts", 19 | "test/**/*.ts", 20 | "typechain/**/*.d.ts", 21 | "typechain/**/*.ts", 22 | "./scripts", 23 | "verify/**/*.js" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /contracts/amm/libraries/SafeMath.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity =0.6.12; 4 | 5 | // a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math) 6 | 7 | library SafeMathUniswap { 8 | function add(uint x, uint y) internal pure returns (uint z) { 9 | require((z = x + y) >= x, 'ds-math-add-overflow'); 10 | } 11 | 12 | function sub(uint x, uint y) internal pure returns (uint z) { 13 | require((z = x - y) <= x, 'ds-math-sub-underflow'); 14 | } 15 | 16 | function mul(uint x, uint y) internal pure returns (uint z) { 17 | require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.solcover.js: -------------------------------------------------------------------------------- 1 | const shell = require("shelljs"); 2 | 3 | // The environment variables are loaded in hardhat.config.ts 4 | const mnemonic = process.env.MNEMONIC; 5 | if (!mnemonic) { 6 | throw new Error("Please set your MNEMONIC in a .env file"); 7 | } 8 | 9 | module.exports = { 10 | istanbulReporter: ["html", "lcov"], 11 | onCompileComplete: async function (_config) { 12 | await run("typechain"); 13 | }, 14 | onIstanbulComplete: async function (_config) { 15 | // We need to do this because solcover generates bespoke artifacts. 16 | shell.rm("-rf", "./artifacts"); 17 | shell.rm("-rf", "./typechain"); 18 | }, 19 | providerOptions: { 20 | mnemonic, 21 | }, 22 | skipFiles: ["mocks", "test"], 23 | }; 24 | -------------------------------------------------------------------------------- /contracts/amm/libraries/UQ112x112.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity =0.6.12; 4 | 5 | // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format)) 6 | 7 | // range: [0, 2**112 - 1] 8 | // resolution: 1 / 2**112 9 | 10 | library UQ112x112 { 11 | uint224 constant Q112 = 2**112; 12 | 13 | // encode a uint112 as a UQ112x112 14 | function encode(uint112 y) internal pure returns (uint224 z) { 15 | z = uint224(y) * Q112; // never overflows 16 | } 17 | 18 | // divide a UQ112x112 by a uint112, returning a UQ112x112 19 | function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) { 20 | z = x / uint224(y); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test Package 2 | 3 | on: [push] 4 | 5 | jobs: 6 | lint: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | - uses: actions/setup-node@v4 11 | with: 12 | node-version: 18 13 | cache: "yarn" 14 | - run: cp .env.example .env 15 | - run: yarn 16 | - run: yarn compile 17 | - run: yarn lint 18 | test: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/checkout@v4 22 | - uses: actions/setup-node@v4 23 | with: 24 | node-version: 18 25 | cache: "yarn" 26 | - run: cp .env.example .env 27 | - run: yarn 28 | - run: yarn compile 29 | - run: yarn test 30 | -------------------------------------------------------------------------------- /contracts/amm/libraries/Math.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity =0.6.12; 4 | 5 | // a library for performing various math operations 6 | 7 | library Math { 8 | function min(uint x, uint y) internal pure returns (uint z) { 9 | z = x < y ? x : y; 10 | } 11 | 12 | // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) 13 | function sqrt(uint y) internal pure returns (uint z) { 14 | if (y > 3) { 15 | z = y; 16 | uint x = y / 2 + 1; 17 | while (x < z) { 18 | z = x; 19 | x = (y / x + x) / 2; 20 | } 21 | } else if (y != 0) { 22 | z = 1; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /contracts/mocks/StableLpMakerExploitMockV2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | pragma experimental ABIEncoderV2; 5 | 6 | import "../rewards/StableLPMakerV2.sol"; 7 | 8 | contract StableLpMakerExploitMockV2 { 9 | StableLPMakerV2 public immutable stableLpMaker; 10 | 11 | constructor(address _stableLpMaker) public { 12 | stableLpMaker = StableLPMakerV2(_stableLpMaker); 13 | } 14 | 15 | function convertStables( 16 | address[] calldata stableSwaps, 17 | address[] calldata swaps, 18 | uint8[] calldata stableTokensIndexFrom, 19 | uint8[] calldata stableTokensIndexTo 20 | ) external { 21 | stableLpMaker.convertStables(stableSwaps, swaps, stableTokensIndexFrom, stableTokensIndexTo); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /contracts/amm/interfaces/IUniswapV2Factory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | interface IUniswapV2Factory { 6 | event PairCreated(address indexed token0, address indexed token1, address pair, uint); 7 | 8 | function feeTo() external view returns (address); 9 | function feeToSetter() external view returns (address); 10 | function migrator() external view returns (address); 11 | 12 | function getPair(address tokenA, address tokenB) external view returns (address pair); 13 | function allPairs(uint) external view returns (address pair); 14 | function allPairsLength() external view returns (uint); 15 | 16 | function createPair(address tokenA, address tokenB) external returns (address pair); 17 | 18 | function setFeeTo(address) external; 19 | function setFeeToSetter(address) external; 20 | function setMigrator(address) external; 21 | } 22 | -------------------------------------------------------------------------------- /contracts/amm/interfaces/IERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | interface IERC20Uniswap { 6 | event Approval(address indexed owner, address indexed spender, uint value); 7 | event Transfer(address indexed from, address indexed to, uint value); 8 | 9 | function name() external view returns (string memory); 10 | function symbol() external view returns (string memory); 11 | function decimals() external view returns (uint8); 12 | function totalSupply() external view returns (uint); 13 | function balanceOf(address owner) external view returns (uint); 14 | function allowance(address owner, address spender) external view returns (uint); 15 | 16 | function approve(address spender, uint value) external returns (bool); 17 | function transfer(address to, uint value) external returns (bool); 18 | function transferFrom(address from, address to, uint value) external returns (bool); 19 | } 20 | -------------------------------------------------------------------------------- /contracts/mocks/StableLpMakerExploitMockV3.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | pragma experimental ABIEncoderV2; 5 | 6 | import "../rewards/StableLPMakerV3.sol"; 7 | 8 | contract StableLpMakerExploitMockV3 { 9 | StableLPMakerV3 public immutable stableLpMaker; 10 | 11 | constructor(address _stableLpMaker) public { 12 | stableLpMaker = StableLPMakerV3(_stableLpMaker); 13 | } 14 | 15 | function convertStables( 16 | address[] calldata stableSwaps, 17 | address[] calldata removeLiquiditySwaps, 18 | address[] calldata swaps, 19 | uint8[] calldata stableTokensIndexFrom, 20 | uint8[] calldata stableTokensIndexTo 21 | ) external { 22 | stableLpMaker.convertStables( 23 | stableSwaps, 24 | removeLiquiditySwaps, 25 | swaps, 26 | stableTokensIndexFrom, 27 | stableTokensIndexTo 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /contracts/mocks/EscrowMock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 6 | 7 | contract EscrowMock is ERC20 { 8 | constructor( 9 | string memory name, 10 | string memory symbol, 11 | uint8 decimals, 12 | uint256 supply 13 | ) public ERC20(name, symbol) { 14 | _setupDecimals(decimals); 15 | _mint(msg.sender, supply); 16 | } 17 | 18 | function deposit( 19 | address account, 20 | address token, 21 | uint256 amount 22 | ) public virtual { 23 | ERC20(token).transferFrom(account, address(this), amount); 24 | _mint(account, amount); 25 | } 26 | 27 | function withdraw( 28 | address account, 29 | address token, 30 | uint256 amount 31 | ) public virtual { 32 | ERC20(token).transfer(account, amount); 33 | _burn(account, amount); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /contracts/interfaces/IMasterChefV2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.6.12; 3 | pragma experimental ABIEncoderV2; 4 | 5 | interface IMasterChefV2 { 6 | struct UserInfo { 7 | uint256 amount; // How many LP tokens the user has provided. 8 | uint256 rewardDebt; // Reward debt. See explanation below. 9 | } 10 | 11 | struct PoolInfo { 12 | uint256 allocPoint; // How many allocation points assigned to this pool. SUSHI to distribute per block. 13 | uint256 lastRewardBlock; // Last block number that SUSHI distribution occurs. 14 | uint256 accSushiPerShare; // Accumulated SUSHI per share, times 1e12. See below. 15 | } 16 | 17 | function poolInfo(uint256 pid) external view returns (IMasterChefV2.PoolInfo memory); 18 | 19 | function totalAllocPoint() external view returns (uint256); 20 | 21 | function deposit( 22 | uint256 _pid, 23 | uint256 _amount, 24 | address to 25 | ) external; 26 | 27 | function triPerBlock() external view returns (uint256); 28 | 29 | function pendingTri(uint256 _pid, address _user) external view returns (uint256); 30 | } 31 | -------------------------------------------------------------------------------- /contracts/stableswap/OwnerPausableUpgradeable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; 6 | import "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol"; 7 | 8 | /** 9 | * @title OwnerPausable 10 | * @notice An ownable contract allows the owner to pause and unpause the 11 | * contract without a delay. 12 | * @dev Only methods using the provided modifiers will be paused. 13 | */ 14 | abstract contract OwnerPausableUpgradeable is 15 | OwnableUpgradeable, 16 | PausableUpgradeable 17 | { 18 | function __OwnerPausable_init() internal initializer { 19 | __Context_init_unchained(); 20 | __Ownable_init_unchained(); 21 | __Pausable_init_unchained(); 22 | } 23 | 24 | /** 25 | * @notice Pause the contract. Revert if already paused. 26 | */ 27 | function pause() external onlyOwner { 28 | PausableUpgradeable._pause(); 29 | } 30 | 31 | /** 32 | * @notice Unpause the contract. Revert if already unpaused. 33 | */ 34 | function unpause() external onlyOwner { 35 | PausableUpgradeable._unpause(); 36 | } 37 | } -------------------------------------------------------------------------------- /contracts/interfaces/IMasterChef.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.6.12; 3 | pragma experimental ABIEncoderV2; 4 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 5 | 6 | interface IMasterChef { 7 | struct UserInfo { 8 | uint256 amount; // How many LP tokens the user has provided. 9 | uint256 rewardDebt; // Reward debt. See explanation below. 10 | } 11 | 12 | struct PoolInfo { 13 | IERC20 lpToken; // Address of LP token contract. 14 | uint256 allocPoint; // How many allocation points assigned to this pool. SUSHI to distribute per block. 15 | uint256 lastRewardBlock; // Last block number that SUSHI distribution occurs. 16 | uint256 accSushiPerShare; // Accumulated SUSHI per share, times 1e12. See below. 17 | } 18 | 19 | function poolInfo(uint256 pid) external view returns (IMasterChef.PoolInfo memory); 20 | 21 | function totalAllocPoint() external view returns (uint256); 22 | 23 | function deposit(uint256 _pid, uint256 _amount) external; 24 | 25 | function triPerBlock() external view returns (uint256); 26 | 27 | function pendingTri(uint256 _pid, address _user) external view returns (uint256); 28 | } 29 | -------------------------------------------------------------------------------- /contracts/amm/interfaces/IUniswapV2ERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | interface IUniswapV2ERC20 { 6 | event Approval(address indexed owner, address indexed spender, uint value); 7 | event Transfer(address indexed from, address indexed to, uint value); 8 | 9 | function name() external pure returns (string memory); 10 | function symbol() external pure returns (string memory); 11 | function decimals() external pure returns (uint8); 12 | function totalSupply() external view returns (uint); 13 | function balanceOf(address owner) external view returns (uint); 14 | function allowance(address owner, address spender) external view returns (uint); 15 | 16 | function approve(address spender, uint value) external returns (bool); 17 | function transfer(address to, uint value) external returns (bool); 18 | function transferFrom(address from, address to, uint value) external returns (bool); 19 | 20 | function DOMAIN_SEPARATOR() external view returns (bytes32); 21 | function PERMIT_TYPEHASH() external pure returns (bytes32); 22 | function nonces(address owner) external view returns (uint); 23 | 24 | function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; 25 | } -------------------------------------------------------------------------------- /contracts/stableswap/MathUtils.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import "@openzeppelin/contracts/math/SafeMath.sol"; 6 | 7 | /** 8 | * @title MathUtils library 9 | * @notice A library to be used in conjunction with SafeMath. Contains functions for calculating 10 | * differences between two uint256. 11 | */ 12 | library MathUtils { 13 | /** 14 | * @notice Compares a and b and returns true if the difference between a and b 15 | * is less than 1 or equal to each other. 16 | * @param a uint256 to compare with 17 | * @param b uint256 to compare with 18 | * @return True if the difference between a and b is less than 1 or equal, 19 | * otherwise return false 20 | */ 21 | function within1(uint256 a, uint256 b) internal pure returns (bool) { 22 | return (difference(a, b) <= 1); 23 | } 24 | 25 | /** 26 | * @notice Calculates absolute difference between a and b 27 | * @param a uint256 to compare with 28 | * @param b uint256 to compare with 29 | * @return Difference between a and b 30 | */ 31 | function difference(uint256 a, uint256 b) internal pure returns (uint256) { 32 | if (a > b) { 33 | return a - b; 34 | } 35 | return b - a; 36 | } 37 | } -------------------------------------------------------------------------------- /scripts/verify/xtri.ts: -------------------------------------------------------------------------------- 1 | // We require the Hardhat Runtime Environment explicitly here. This is optional 2 | // but useful for running the script in a standalone fashion through `node