├── .gas-snapshot
├── .github
└── workflows
│ └── test.yml
├── .gitignore
├── .gitmodules
├── .husky
└── pre-commit
├── .prettierignore
├── CODEOWNER
├── COPYING
├── README.md
├── audit
└── Certik-Audit-CyberConnect.pdf
├── config
├── .solhint.json
└── .solhintignore
├── docs
├── README.md
├── abi
│ ├── CollectDisallowedMw.json
│ ├── CollectFlexPaidMw.json
│ ├── CollectLimitedTimePaidMw.json
│ ├── CollectMerkleDropMw.json
│ ├── CollectOnlySubscribedMw.json
│ ├── CollectPaidMw.json
│ ├── CollectPermissionMw.json
│ ├── CollectPermissionPaidMw.json
│ ├── CyberBoxNFT.json
│ ├── CyberEngine.json
│ ├── CyberGrandNFT.json
│ ├── CyberVault.json
│ ├── EssenceNFT.json
│ ├── FrameNFT.json
│ ├── Link3ProfileDescriptor.json
│ ├── MBNFT.json
│ ├── MiniShardNFT.json
│ ├── PaidCollectMw.json
│ ├── PaidSubscribeMw.json
│ ├── PermissionedFeeCreationMw.json
│ ├── ProfileNFT.json
│ ├── RelationshipChecker.json
│ ├── RolesAuthority.json
│ ├── SignaturePermissionEssenceMw.json
│ ├── StableFeeCreationMw.json
│ ├── SubscribeDisallowedMw.json
│ ├── SubscribeNFT.json
│ ├── SubscribeOnlyOnceMw.json
│ ├── SubscribePaidMw.json
│ └── Treasury.json
├── deploy
│ ├── bnb-56
│ │ └── contract.md
│ ├── bnbt-97
│ │ └── contract.md
│ ├── goerli-5
│ │ └── contract.md
│ └── polygon-137
│ │ └── contract.md
├── template
│ ├── anvil-31337
│ │ └── bafkreifjwei5tuvh5zjk7r6ti4wt7eon7dwnobchdinfmdzqhl2l2lrgve
│ ├── bnb-56
│ │ └── bafkreiblu7mqgd43bmenvsyfcp33pkrtjyc52ofwectc2257uicatn6vzm
│ ├── bnbt-97
│ │ └── bafkreigqqa3tkzqkl7bjylkya5nf5qsyyjcunsp4ix525icn5nycf7nw2m
│ ├── goerli-5
│ │ └── bafkreic7ur7evrpy45md2xpth3zvy4mjcczzodjg7xciupty6dvmliye6i
│ ├── mainnet-1
│ │ └── bafkreigjfjobgbh6voodb4z4u3nfpuchwb5usolon6i67kecelki2uzb6y
│ ├── nova-42170
│ │ └── bafkreiaiurmd4gpnu4nqjlddbt2r57ipshpsz77bf7mybun36psiggrbui
│ ├── polygon-137
│ │ └── bafkreiebcj2it5hirwrfbfhjlwr7pxbjqvojtxht4bcjhvvnjxqwomqqly
│ └── rinkeby-4
│ │ └── bafkreifq5vu6gl4q4c5fb23m5w3wyijumonpfb7dki7eodx2222ogfb3lu
└── test
│ └── qrcode.md
├── foundry.toml
├── hardhat-scripts
└── deployActions.ts
├── hardhat.config.ts
├── misc
├── cyberbox
│ └── metadata.json
├── post_deploy.ts
├── pre_deploy.js
├── qrcode
│ ├── QRSVG.t.sol.template
│ ├── gen-html.js
│ ├── gen-sol.js
│ ├── puppet.js
│ └── qr-test.html.template
└── set_animation_url.ts
├── package.json
├── remappings.txt
├── script
├── AllowCurrency.s.sol
├── Deploy.s.sol
├── DeployAction.s.sol
├── DeployBox.s.sol
├── DeployChecker.s.sol
├── DeployCreate2Deployer.s.sol
├── DeployCyberToken.s.sol
├── DeployFrame.s.sol
├── DeployGrand.s.sol
├── DeployMB.s.sol
├── DeployMiddleware.s.sol
├── DeployMiniShard.s.sol
├── DeployNamespace.s.sol
├── DeployPermissionless.s.sol
├── DeployTimeLock.s.sol
├── DeployVault.s.sol
├── RegisterProfile.s.sol
├── SetAniURL.s.sol
├── SetAnimationURLV3.s.sol
├── SetFeeCreationMw.s.sol
├── SetProfileMw.s.sol
├── SetSigner.s.sol
├── SetStableFeeMw.s.sol
├── Tmp.s.sol
├── animation_url
│ ├── anvil-31337
│ │ ├── SetAnimationURL.s.sol
│ │ └── SetAnimationURL.s.sol.template
│ ├── bnb-56
│ │ ├── SetAnimationURL.s.sol
│ │ └── SetAnimationURL.s.sol.template
│ ├── bnbt-97
│ │ ├── SetAnimationURL.s.sol
│ │ └── SetAnimationURL.s.sol.template
│ ├── goerli-5
│ │ ├── SetAnimationURL.s.sol
│ │ └── SetAnimationURL.s.sol.template
│ ├── mainnet-1
│ │ ├── SetAnimationURL.s.sol
│ │ └── SetAnimationURL.s.sol.template
│ ├── nova-42170
│ │ ├── SetAnimationURL.s.sol
│ │ └── SetAnimationURL.s.sol.template
│ ├── polygon-137
│ │ ├── SetAnimationURL.s.sol
│ │ └── SetAnimationURL.s.sol.template
│ └── rinkeby-4
│ │ ├── SetAnimationURL.s.sol
│ │ └── SetAnimationURL.s.sol.template
├── libraries
│ ├── DeployNamespace.sol
│ ├── DeploySetting.sol
│ └── LibDeploy.sol
└── mainnet-upgrades
│ └── 2022-7-18
│ └── UpgradeProfileMiddleware.s.sol
├── slither.config.json
├── src
├── base
│ ├── CyberNFTBase.sol
│ ├── CyberNFTBaseFlex.sol
│ └── EIP712.sol
├── core
│ ├── CyberEngine.sol
│ ├── EssenceNFT.sol
│ ├── ProfileNFT.sol
│ └── SubscribeNFT.sol
├── dependencies
│ ├── openzeppelin
│ │ ├── Pausable.sol
│ │ └── ReentrancyGuard.sol
│ └── solmate
│ │ ├── Auth.sol
│ │ ├── ERC721.sol
│ │ ├── Owned.sol
│ │ └── RolesAuthority.sol
├── deployer
│ ├── Create2Deployer.sol
│ ├── EssenceDeployer.sol
│ ├── ProfileDeployer.sol
│ └── SubscribeDeployer.sol
├── interfaces
│ ├── ICyberBox.sol
│ ├── ICyberBoxEvents.sol
│ ├── ICyberEngine.sol
│ ├── ICyberEngineEvents.sol
│ ├── ICyberGrand.sol
│ ├── ICyberGrandEvents.sol
│ ├── ICyberNFTBase.sol
│ ├── IEssenceDeployer.sol
│ ├── IEssenceMiddleware.sol
│ ├── IEssenceNFT.sol
│ ├── IEssenceNFTEvents.sol
│ ├── IMB.sol
│ ├── IMBEvents.sol
│ ├── IProfileDeployer.sol
│ ├── IProfileMiddleware.sol
│ ├── IProfileNFT.sol
│ ├── IProfileNFTDescriptor.sol
│ ├── IProfileNFTDescriptorV2.sol
│ ├── IProfileNFTEvents.sol
│ ├── ISubscribeDeployer.sol
│ ├── ISubscribeMiddleware.sol
│ ├── ISubscribeNFT.sol
│ ├── ISubscribeNFTEvents.sol
│ ├── ITreasury.sol
│ ├── ITreasuryEvents.sol
│ └── IUpgradeable.sol
├── libraries
│ ├── Actions.sol
│ ├── Constants.sol
│ ├── DataTypes.sol
│ ├── LibString.sol
│ └── QRSVG.sol
├── middlewares
│ ├── base
│ │ ├── FeeMw.sol
│ │ ├── PermissionedMw.sol
│ │ └── Treasury.sol
│ ├── essence
│ │ ├── CollectDisallowedMw.sol
│ │ ├── CollectFlexPaidMw.sol
│ │ ├── CollectLimitedTimePaidMw.sol
│ │ ├── CollectMerkleDropMw.sol
│ │ ├── CollectOnlySubscribedMw.sol
│ │ ├── CollectPaidMw.sol
│ │ ├── CollectPermissionMw.sol
│ │ └── CollectPermissionPaidMw.sol
│ ├── profile
│ │ ├── FeeCreationMw.sol
│ │ ├── PermissionedFeeCreationMw.sol
│ │ └── StableFeeCreationMw.sol
│ └── subscribe
│ │ ├── SubscribeDisallowedMw.sol
│ │ ├── SubscribeOnlyOnceMw.sol
│ │ └── SubscribePaidMw.sol
├── periphery
│ ├── CyberBoxNFT.sol
│ ├── CyberGrandNFT.sol
│ ├── CyberVault.sol
│ ├── FrameNFT.sol
│ ├── Link3ProfileDescriptor.sol
│ ├── Link3ProfileDescriptorV2.sol
│ ├── Link3ProfileDescriptorV3.sol
│ ├── MBNFT.sol
│ ├── MiniShardNFT.sol
│ └── RelationshipChecker.sol
├── storages
│ ├── CyberBoxNFTStorage.sol
│ ├── CyberEngineStorage.sol
│ ├── CyberGrandNFTStorage.sol
│ ├── EssenceNFTStorage.sol
│ ├── Link3ProfileDescriptorStorage.sol
│ ├── Link3ProfileDescriptorStorageV2.sol
│ ├── MBNFTStorage.sol
│ ├── ProfileNFTStorage.sol
│ └── SubscribeNFTStorage.sol
├── token
│ └── CYBER.sol
└── upgradeability
│ └── UpgradeableBeacon.sol
├── template
└── index.html
├── test
├── CyberEngine.t.sol
├── CyberEngineUpgrade.t.sol
├── CyberNFTBase.t.sol
├── CyberToken.t.sol
├── Deployer.t.sol
├── EssenceNFT.t.sol
├── LibString.t.sol
├── Pausable.t.sol
├── ProfileNFT.t.sol
├── ProfileNFTBehavior.sol
├── ProfileNFTUpgrade.t.sol
├── QRSVGBasic.t.sol
├── SubscribeNFT.t.sol
├── SubscribeNFTUpgrade.t.sol
├── Treasury.t.sol
├── UpgradeableBeacon.t.sol
├── integration
│ ├── IntegrationBase.t.sol
│ ├── IntegrationCollect.t.sol
│ ├── IntegrationEngine.t.sol
│ ├── IntegrationSubscribe.t.sol
│ ├── IntegrationTimelock.t.sol
│ └── middleware
│ │ ├── essence
│ │ ├── CollectDisallowedMw.t.sol
│ │ ├── CollectFlexPaidMw.t.sol
│ │ ├── CollectMerkleDropMw.t.sol
│ │ ├── CollectPaidMw.t.sol
│ │ └── CollectPermissionMw.t.sol
│ │ ├── profile
│ │ └── PermissionedFeeCreationMw.t.sol
│ │ └── subscribe
│ │ ├── SubscribeDisallowedMw.t.sol
│ │ ├── SubscribeOnlyOnceMw.t.sol
│ │ └── SubscribePaidMw.t.sol
├── periphery
│ ├── CyberBoxNFT.t.sol
│ ├── CyberBoxNFTUpgrade.t.sol
│ ├── CyberVault.t.sol
│ └── Link3ProfileDescriptor.t.sol
└── utils
│ ├── MockCyberBoxV2.sol
│ ├── MockERC1155.sol
│ ├── MockERC20.sol
│ ├── MockERC721.sol
│ ├── MockEngine.sol
│ ├── MockEngineV2.sol
│ ├── MockInitializable.sol
│ ├── MockLink5NFTDescriptor.sol
│ ├── MockNFT.sol
│ ├── MockPausable.sol
│ ├── MockProfile.sol
│ ├── MockProfileV2.sol
│ ├── MockSubscribeNFTV2.sol
│ ├── TestDeployer.sol
│ ├── TestIntegrationBase.sol
│ ├── TestLib712.sol
│ ├── TestLibFixture.sol
│ └── TestProxy.sol
├── tsconfig.json
└── yarn.lock
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: test
2 |
3 | on: [push]
4 |
5 | env:
6 | FOUNDRY_PROFILE: default
7 |
8 | jobs:
9 | check:
10 | strategy:
11 | fail-fast: true
12 |
13 | name: Foundry project
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@v3
17 | with:
18 | submodules: recursive
19 |
20 | - name: Install Foundry
21 | uses: foundry-rs/foundry-toolchain@v1
22 | with:
23 | version: nightly
24 |
25 | # - name: Check gas snapshots
26 | # run: forge snapshot --check
27 |
28 | - name: Run Forge tests
29 | run: |
30 | forge test -vvv --gas-report
31 | id: test
32 |
33 | - uses: actions/setup-node@v3
34 | with:
35 | node-version: 14
36 |
37 | - name: Install modules
38 | run: yarn
39 |
40 | - name: Run lint
41 | run: yarn run lint:gh-check
42 |
43 | - name: Run Coverage
44 | run: forge coverage --report lcov
45 |
46 | - name: Upload coverage to Codecov
47 | uses: codecov/codecov-action@v3
48 | with:
49 | token: 5988e766-42d2-43ef-813c-56f5b7cbcc6d
50 | directory: .
51 | env_vars: OS,PYTHON
52 | fail_ci_if_error: true
53 | files: ./lcov.info
54 | name: cybercontracts-coverage
55 | verbose: true
56 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | cache/
2 | cache_hardhat/
3 | out/
4 | node_modules
5 | .env*
6 | .constructor-args*
7 | broadcast/
8 | .DS_Store
9 | artifacts/
10 | test/qrcode
11 | misc/qrcode/svg
12 | misc/qrcode/html
13 | script/playground
14 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "lib/forge-std"]
2 | path = lib/forge-std
3 | url = https://github.com/foundry-rs/forge-std
4 | [submodule "lib/openzeppelin-contracts"]
5 | path = lib/openzeppelin-contracts
6 | url = https://github.com/OpenZeppelin/openzeppelin-contracts
7 | branch = release-v4.7
8 | [submodule "lib/chainlink"]
9 | path = lib/chainlink
10 | url = https://github.com/smartcontractkit/chainlink
11 | branch = v1.11.0
12 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | . "$(dirname -- "$0")/_/husky.sh"
3 |
4 | npx lint-staged && forge test -vvv && forge snapshot --check
5 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | lib
3 | src/dependencies/
4 | misc/qrcode/html/
5 | src/upgradeability/
--------------------------------------------------------------------------------
/CODEOWNER:
--------------------------------------------------------------------------------
1 | /src/dependencies/ @ZhimaoL @ryanli-me
--------------------------------------------------------------------------------
/audit/Certik-Audit-CyberConnect.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyberconnecthq/cybercontracts/acf96eb70dc5d20cd8e9d1e79dd81bffd5aa9fff/audit/Certik-Audit-CyberConnect.pdf
--------------------------------------------------------------------------------
/config/.solhint.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["prettier"],
3 | "extends": "solhint:recommended",
4 | "rules": {
5 | "prettier/prettier": "error",
6 | "compiler-version": ["error", "^0.8.14"],
7 | "no-empty-blocks": "off",
8 | "func-visibility": ["warn", { "ignoreConstructors": true }],
9 | "quotes": ["off", "double"],
10 | "not-rely-on-time": "off"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/config/.solhintignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | lib/
3 | src/dependencies/
4 | src/libraries/LibString.sol
5 | src/upgradeability/
6 | src/dependencies/
7 | src/base/Auth.sol
8 | src/base/ERC721.sol
9 | src/base/RolesAuthority.sol
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Rinkeby
2 |
3 | [deployment](./deploy/rinkeby.md)
--------------------------------------------------------------------------------
/docs/abi/CollectDisallowedMw.json:
--------------------------------------------------------------------------------
1 | [{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"postProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"preProcess","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"setEssenceMwData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"}]
--------------------------------------------------------------------------------
/docs/abi/CollectFlexPaidMw.json:
--------------------------------------------------------------------------------
1 | [{"inputs":[{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"namespace","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"profileId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"essenceId","type":"uint256"},{"indexed":true,"internalType":"address","name":"collector","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"metadataId","type":"string"}],"name":"CollectFlexPaidMwPreprocessed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"namespace","type":"address"},{"indexed":true,"internalType":"uint256","name":"profileId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"essenceId","type":"uint256"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"}],"name":"CollectFlexPaidMwSet","type":"event"},{"inputs":[],"name":"TREASURY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"postProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"essenceId","type":"uint256"},{"internalType":"address","name":"collector","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"preProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"essenceId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setEssenceMwData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"}]
--------------------------------------------------------------------------------
/docs/abi/CollectLimitedTimePaidMw.json:
--------------------------------------------------------------------------------
1 | [{"inputs":[{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"namespace","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"namespace","type":"address"},{"indexed":true,"internalType":"uint256","name":"profileId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"essenceId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"uint256","name":"endTimestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTimestamp","type":"uint256"},{"indexed":false,"internalType":"bool","name":"profileRequired","type":"bool"},{"indexed":false,"internalType":"bool","name":"subscribeRequired","type":"bool"}],"name":"CollectLimitedTimePaidMwSet","type":"event"},{"inputs":[],"name":"TREASURY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"postProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"essenceId","type":"uint256"},{"internalType":"address","name":"collector","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"preProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"essenceId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setEssenceMwData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"}]
--------------------------------------------------------------------------------
/docs/abi/CollectMerkleDropMw.json:
--------------------------------------------------------------------------------
1 | [{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"namespace","type":"address"},{"indexed":true,"internalType":"uint256","name":"profileId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"essenceId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"CollectMerkleDropMwSet","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"postProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"essenceId","type":"uint256"},{"internalType":"address","name":"collector","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"preProcess","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"essenceId","type":"uint256"},{"internalType":"bytes","name":"root","type":"bytes"}],"name":"setEssenceMwData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"}]
--------------------------------------------------------------------------------
/docs/abi/CollectOnlySubscribedMw.json:
--------------------------------------------------------------------------------
1 | [{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"postProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"collector","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"preProcess","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"setEssenceMwData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"}]
--------------------------------------------------------------------------------
/docs/abi/CollectPaidMw.json:
--------------------------------------------------------------------------------
1 | [{"inputs":[{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"namespace","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"namespace","type":"address"},{"indexed":true,"internalType":"uint256","name":"profileId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"essenceId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"bool","name":"subscribeRequired","type":"bool"}],"name":"CollectPaidMwSet","type":"event"},{"inputs":[],"name":"TREASURY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"postProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"essenceId","type":"uint256"},{"internalType":"address","name":"collector","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"preProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"essenceId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setEssenceMwData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"}]
--------------------------------------------------------------------------------
/docs/abi/CollectPermissionMw.json:
--------------------------------------------------------------------------------
1 | [{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"namespace","type":"address"},{"indexed":true,"internalType":"uint256","name":"profileId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"essenceId","type":"uint256"},{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"CollectPermissionMwSet","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"namespace","type":"address"},{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"address","name":"collector","type":"address"},{"internalType":"uint256","name":"essenceId","type":"uint256"}],"name":"getNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"postProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"essenceId","type":"uint256"},{"internalType":"address","name":"collector","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"preProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"essenceId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setEssenceMwData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"}]
--------------------------------------------------------------------------------
/docs/abi/CollectPermissionPaidMw.json:
--------------------------------------------------------------------------------
1 | [{"inputs":[{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"namespace","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"namespace","type":"address"},{"indexed":true,"internalType":"uint256","name":"profileId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"essenceId","type":"uint256"},{"indexed":false,"internalType":"address","name":"signer","type":"address"},{"indexed":false,"internalType":"uint256","name":"totalSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"address","name":"currency","type":"address"}],"name":"CollectPermissionPaidMwSet","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TREASURY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"address","name":"collector","type":"address"},{"internalType":"uint256","name":"essenceId","type":"uint256"}],"name":"getNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"postProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"essenceId","type":"uint256"},{"internalType":"address","name":"collector","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"preProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"essenceId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setEssenceMwData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"}]
--------------------------------------------------------------------------------
/docs/abi/Link3ProfileDescriptor.json:
--------------------------------------------------------------------------------
1 | [{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"preTemplate","type":"string"},{"indexed":false,"internalType":"string","name":"template","type":"string"}],"name":"SetAnimationTemplate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"animationTemplate","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_animationTemplate","type":"string"},{"internalType":"address","name":"_owner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"template","type":"string"}],"name":"setAnimationTemplate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"handle","type":"string"},{"internalType":"uint256","name":"subscribers","type":"uint256"}],"internalType":"struct DataTypes.ConstructTokenURIParams","name":"params","type":"tuple"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"}]
--------------------------------------------------------------------------------
/docs/abi/PaidCollectMw.json:
--------------------------------------------------------------------------------
1 | [{"inputs":[{"internalType":"address","name":"treasury","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"namespace","type":"address"},{"indexed":true,"internalType":"uint256","name":"profileId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"essenceId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"currentCollect","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"bool","name":"subscribeRequired","type":"bool"}],"name":"PaidEssenceMwSet","type":"event"},{"inputs":[],"name":"TREASURY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"postProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"essenceId","type":"uint256"},{"internalType":"address","name":"collector","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"preProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"essenceId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setEssenceMwData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"}]
--------------------------------------------------------------------------------
/docs/abi/PaidSubscribeMw.json:
--------------------------------------------------------------------------------
1 | [{"inputs":[{"internalType":"address","name":"treasury","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"namespace","type":"address"},{"indexed":true,"internalType":"uint256","name":"profileId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"bool","name":"nftRequired","type":"bool"},{"indexed":false,"internalType":"address","name":"nftAddress","type":"address"}],"name":"PaidSubscribeMwSet","type":"event"},{"inputs":[],"name":"TREASURY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"postProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"address","name":"subscriber","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"preProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setSubscribeMwData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"}]
--------------------------------------------------------------------------------
/docs/abi/PermissionedFeeCreationMw.json:
--------------------------------------------------------------------------------
1 | [{"inputs":[{"internalType":"address","name":"engine","type":"address"},{"internalType":"address","name":"treasury","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"namespace","type":"address"},{"indexed":false,"internalType":"enum PermissionedFeeCreationMw.Tier","name":"tier","type":"uint8"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SetFeeByTier","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ENGINE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TREASURY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"namespace","type":"address"},{"internalType":"enum PermissionedFeeCreationMw.Tier","name":"tier","type":"uint8"}],"name":"getFeeByTier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"namespace","type":"address"},{"internalType":"address","name":"user","type":"address"}],"name":"getNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"namespace","type":"address"}],"name":"getRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"namespace","type":"address"}],"name":"getSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"handle","type":"string"},{"internalType":"string","name":"avatar","type":"string"},{"internalType":"string","name":"metadata","type":"string"},{"internalType":"address","name":"operator","type":"address"}],"internalType":"struct DataTypes.CreateProfileParams","name":"params","type":"tuple"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"postProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"handle","type":"string"},{"internalType":"string","name":"avatar","type":"string"},{"internalType":"string","name":"metadata","type":"string"},{"internalType":"address","name":"operator","type":"address"}],"internalType":"struct DataTypes.CreateProfileParams","name":"params","type":"tuple"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"preProcess","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"namespace","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setProfileMwData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"}]
--------------------------------------------------------------------------------
/docs/abi/RelationshipChecker.json:
--------------------------------------------------------------------------------
1 | [{"inputs":[{"internalType":"address","name":"namespace","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"essenceId","type":"uint256"},{"internalType":"address","name":"me","type":"address"}],"name":"isCollectedByMe","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"address","name":"me","type":"address"}],"name":"isSubscribedByMe","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
--------------------------------------------------------------------------------
/docs/abi/SignaturePermissionEssenceMw.json:
--------------------------------------------------------------------------------
1 | [{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"namespace","type":"address"},{"indexed":true,"internalType":"uint256","name":"profileId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"essenceId","type":"uint256"},{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"SignatureEssenceMwSignerSet","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"address","name":"collector","type":"address"},{"internalType":"uint256","name":"essenceId","type":"uint256"}],"name":"getNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"postProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"essenceId","type":"uint256"},{"internalType":"address","name":"collector","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"preProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"essenceId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setEssenceMwData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"}]
--------------------------------------------------------------------------------
/docs/abi/SubscribeDisallowedMw.json:
--------------------------------------------------------------------------------
1 | [{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"address","name":"subscriber","type":"address"},{"internalType":"address","name":"subscribeNFT","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"postProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"preProcess","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"setSubscribeMwData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"}]
--------------------------------------------------------------------------------
/docs/abi/SubscribeOnlyOnceMw.json:
--------------------------------------------------------------------------------
1 | [{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"address","name":"subscriber","type":"address"},{"internalType":"address","name":"subscribeNFT","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"postProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"subscriber","type":"address"},{"internalType":"address","name":"subscribeNFT","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"preProcess","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"setSubscribeMwData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"}]
--------------------------------------------------------------------------------
/docs/abi/SubscribePaidMw.json:
--------------------------------------------------------------------------------
1 | [{"inputs":[{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"namespace","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"namespace","type":"address"},{"indexed":true,"internalType":"uint256","name":"profileId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"bool","name":"nftRequired","type":"bool"},{"indexed":false,"internalType":"address","name":"nftAddress","type":"address"}],"name":"SubscribePaidMwSet","type":"event"},{"inputs":[],"name":"TREASURY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"postProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"address","name":"subscriber","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"preProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setSubscribeMwData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"}]
--------------------------------------------------------------------------------
/docs/abi/Treasury.json:
--------------------------------------------------------------------------------
1 | [{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"treasuryAddress","type":"address"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"currency","type":"address"},{"indexed":true,"internalType":"bool","name":"preAllowed","type":"bool"},{"indexed":true,"internalType":"bool","name":"newAllowed","type":"bool"}],"name":"AllowCurrency","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"preTreasuryAddress","type":"address"},{"indexed":true,"internalType":"address","name":"treasuryAddress","type":"address"}],"name":"SetTreasuryAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"preTreasuryFee","type":"uint16"},{"indexed":true,"internalType":"uint16","name":"treasuryFee","type":"uint16"}],"name":"SetTreasuryFee","type":"event"},{"inputs":[{"internalType":"address","name":"currency","type":"address"},{"internalType":"bool","name":"allowed","type":"bool"}],"name":"allowCurrency","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getTreasuryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTreasuryFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"currency","type":"address"}],"name":"isCurrencyAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"treasuryAddress","type":"address"}],"name":"setTreasuryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"treasuryFee","type":"uint16"}],"name":"setTreasuryFee","outputs":[],"stateMutability":"nonpayable","type":"function"}]
--------------------------------------------------------------------------------
/docs/deploy/goerli-5/contract.md:
--------------------------------------------------------------------------------
1 | | Contract | Address |
2 | | ----------------------------------------- | ------------------------------------------ |
3 | | Action Lib | 0x781d0a455020024da046f823d9ea076b76a873f3 |
4 | | RolesAuthority | 0x1ae0b199a2180632947721d9c5ebc9daf0ec10e5 |
5 | | EngineImpl | 0xa6fdfff3955455897b746432f945eab3b5fb5c1f |
6 | | EngineProxy | 0xaf9104eb9c6b21efdc43baaaee70662d6cce8798 |
7 | | Profile Factory | 0x27361075ea6e85564a4b00f5828235fc4c8c2e32 |
8 | | Essence Factory | 0x216ba81b5fd81253fde6888039c6001d6f891efb |
9 | | Subscribe Factory | 0x958d142ef3a7b2ee34cdf1f81c135fb91a454a5c |
10 | | CC Profile (Impl) | 0xeD2788C005C8715cFC7C2A29fF81B40b479Cc6fb |
11 | | CC Profile (Proxy) | 0x57e12b7a5f38a7f9c23ebd0400e6e53f2a45f271 |
12 | | CyberConnect Treasury | 0x3963744012dadf90a9034ea1068f53108b1a3834 |
13 | | CC Descriptor (Impl) | 0x74788f90b8436afe91931c17a01023bce5d89c0f |
14 | | CC Descriptor (Proxy) | 0xa27b77f6b13bece78b63925edb3b35df495fdf8e |
15 | | CyberVault | 0x5e2a433774a51207d69bb432898b3626e20cda66 |
16 | | RelationshipChecker | 0xa52cc9b8219dce25bc791a8b253dec61f16d5ff0 |
17 | | CyberGrandNFT (Impl) | 0x4ae6d419b943c6a26b08f8969d5feb987b4e6deb |
18 | | CyberGrandNFT (Proxy) | 0x812f26e1ebacb28d129a02bce016098154335ebd |
19 | | CyberBoxNFT (Proxy) | 0x1cc24a44c4b51d3f9b0d0f5bdcf95b0f385b154f |
20 | | MBNFT (Impl) | 0x4f321fb85f09630d4a6c2295c89da39b4a6f791c |
21 | | MBNFT (Proxy) | 0xff0ab461778232a1480f7886ea1e2abd3324f338 |
22 | | FrameNFT | 0x58d8c07575339bf47392ad2bd0aeb9955f8495cf |
23 | | CC Profile MW (StableFeeCreationMw) | 0x940d11e9105d7c0ffee91e5e6b2375e3a58ec18a |
24 | | CC Profile MW (PermissionedFeeCreationMw) | 0xd1587f68e9d9f9ee93c9aa6fc60c7da414e90818 |
25 | | CC Profile MW (FeeCreationMw) | 0xf1d8512d08f3924768041d1063ef5517ca867f0d |
26 | | Essence MW (SignaturePermissionEssenceMw) | 0x733142f467904f9a2e8efa0119523d3cc7a99b0b |
27 | | Subscribe MW (SubscribePaidMw) | 0xd5d66dc7180fa4f3ae05b66ee34793146db6e3e9 |
28 | | Essence MW (CollectPaidMw) | 0x415648c28adb31629418498264f55d54e4c324db |
29 | | Essence MW (CollectPermissionMw) | 0x77ebd0aa021b39086e84b9d3afeb738cbbfe16fd |
30 | | Essence MW (CollectPermissionMw V2) | 0xbbbab0257edba5823ddb5aa62c08f07bd0d302d9 |
31 | | Essence MW (CollectLimitedTimePaidMw) | 0x3a6507d750c87b219920879f9e01fdd512580872 |
32 |
--------------------------------------------------------------------------------
/docs/deploy/polygon-137/contract.md:
--------------------------------------------------------------------------------
1 | | Contract | Address |
2 | | ------------ | ------------------------------------------ |
3 | | MiniShardNFT | 0x49253c64e6fa46d299177b8a94ae49d2f82c5c95 |
4 |
--------------------------------------------------------------------------------
/docs/test/qrcode.md:
--------------------------------------------------------------------------------
1 | # QRCode Library Fuzz Test
2 |
3 | 0. foundryup
4 | ```bash
5 | foundryup
6 | ```
7 |
8 | clean up
9 | ```bash
10 | rm -rf ./test/qrcode ./misc/qrcode/html ./misc/qrcode/svg
11 | ```
12 | 1. Set desired test parameter (data length and iteration) in `./misc/qrcode/gen-sol.js` to generate solidity test files (300 is probably max)
13 | 2. Run
14 |
15 | ```bash
16 | node misc/qrcode/gen-sol.js
17 | ```
18 |
19 | 3. Make sure you have `./misc/qrcode/svg` folder created.
20 |
21 | ```bash
22 | mkdir -pv misc/qrcode/svg
23 | ```
24 |
25 | 4. Run
26 |
27 | ```bash
28 | forge test --match-contract QRSVGIntegration -vvv
29 | ```
30 |
31 | This runs QRSVG.sol against all generated input cases and write base64 encoded svg of the QRCode to `./misc/qrcode/svg`.
32 |
33 | 5. Run
34 |
35 | ```bash
36 | node misc/qrcode/gen-html.js
37 | ```
38 |
39 | This generates html files for each svg QRCode for verifying the content.
40 |
41 | 6. Run
42 |
43 | ```bash
44 | node misc/qrcode/puppet.js
45 | ```
46 |
47 | This runs a headless chrome for browser to read QRCode with Canvas and check if the content of QRCode is expected
48 |
--------------------------------------------------------------------------------
/foundry.toml:
--------------------------------------------------------------------------------
1 | [profile.default]
2 | src = 'src'
3 | out = 'out'
4 | libs = ['lib']
5 | gas_reports = ["*"]
6 | fs_permissions = [{ access = "read-write", path = "./"}]
7 |
8 | [profile.goerli]
9 | src = 'src'
10 | out = 'out'
11 | libs = ['lib']
12 | gas_reports = ["*"]
13 | libraries = [
14 | './src/libraries/Actions.sol:Actions:0x781d0a455020024da046f823d9ea076b76a873f3'
15 | ]
16 | fs_permissions = [{ access = "read-write", path = "./"}]
17 |
18 | [profile.bnbt]
19 | src = 'src'
20 | out = 'out'
21 | libs = ['lib']
22 | gas_reports = ["*"]
23 | libraries = [
24 | './src/libraries/Actions.sol:Actions:0x781d0a455020024da046f823d9ea076b76a873f3'
25 | ]
26 | fs_permissions = [{ access = "read-write", path = "./"}]
27 |
28 | [profile.mainnet]
29 | src = 'src'
30 | out = 'out'
31 | libs = ['lib']
32 | gas_reports = ["*"]
33 | libraries = [
34 | './src/libraries/Actions.sol:Actions:0x8ccbe07f1e12a61e4fbb3a1895d35dce001ff73a'
35 | ]
36 | fs_permissions = [{ access = "read-write", path = "./"}]
37 |
38 | [profile.nova]
39 | src = 'src'
40 | out = 'out'
41 | libs = ['lib']
42 | gas_reports = ["*"]
43 | libraries = [
44 | './src/libraries/Actions.sol:Actions:0x8ccbe07f1e12a61e4fbb3a1895d35dce001ff73a'
45 | ]
46 | fs_permissions = [{ access = "read-write", path = "./"}]
47 |
48 | [profile.bnb]
49 | src = 'src'
50 | out = 'out'
51 | libs = ['lib']
52 | gas_reports = ["*"]
53 | libraries = [
54 | './src/libraries/Actions.sol:Actions:0x8ccbe07f1e12a61e4fbb3a1895d35dce001ff73a'
55 | ]
56 | fs_permissions = [{ access = "read-write", path = "./"}]
57 |
58 | [profile.polygon]
59 | src = 'src'
60 | out = 'out'
61 | libs = ['lib']
62 | gas_reports = ["*"]
63 | libraries = [
64 | './src/libraries/Actions.sol:Actions:0x8ccbe07f1e12a61e4fbb3a1895d35dce001ff73a'
65 | ]
66 | fs_permissions = [{ access = "read-write", path = "./"}]
67 |
68 |
69 | # See more config options https://github.com/foundry-rs/foundry/tree/master/config
--------------------------------------------------------------------------------
/hardhat.config.ts:
--------------------------------------------------------------------------------
1 | import fs from "fs";
2 | import "hardhat-preprocessor";
3 | import "hardhat-contract-sizer";
4 | import { HardhatUserConfig } from "hardhat/config";
5 | import "@nomiclabs/hardhat-ethers";
6 | require("dotenv").config({ path: __dirname + "/.env.goerli" });
7 | //require("dotenv").config({ path: __dirname + "/.env.bnbt" });
8 | //require("dotenv").config({ path: __dirname + "/.env.bnb" });
9 | //require("dotenv").config({ path: __dirname + "/.env.nova" });
10 |
11 | /** @type import('hardhat/config').HardhatUserConfig */
12 | const config: HardhatUserConfig = {
13 | networks: {
14 | hardhat: {},
15 | goerli: {
16 | url: process.env.GOERLI_RPC_URL,
17 | accounts: [process.env.PRIVATE_KEY as string],
18 | },
19 | // bnbt: {
20 | // url: process.env.BNBT_RPC_URL,
21 | // accounts: [process.env.PRIVATE_KEY as string],
22 | // },
23 | // bnb: {
24 | // url: process.env.BNB_RPC_URL,
25 | // accounts: [process.env.PRIVATE_KEY as string],
26 | // },
27 | // nova: {
28 | // url: process.env.NOVA_RPC_URL,
29 | // accounts: [process.env.PRIVATE_KEY as string],
30 | // },
31 | },
32 | solidity: {
33 | version: "0.8.14",
34 | settings: {
35 | optimizer: {
36 | enabled: true,
37 | runs: 200,
38 | },
39 | },
40 | },
41 | preprocess: {
42 | eachLine: (hre: any) => ({
43 | transform: (line: string) => {
44 | if (line.match(/^\s*import /i)) {
45 | getRemappings().forEach(([find, replace]) => {
46 | // this matches all occurrences not just the start of import which could be a problem
47 | if (line.match(find)) {
48 | line = line.replace(find, replace);
49 | }
50 | });
51 | }
52 | return line;
53 | },
54 | }),
55 | },
56 | paths: {
57 | sources: "./src",
58 | cache: "./cache_hardhat",
59 | },
60 | };
61 | function getRemappings() {
62 | return fs
63 | .readFileSync("remappings.txt", "utf8")
64 | .split("\n")
65 | .filter(Boolean) // remove empty lines
66 | .map((line) => line.trim().split("="));
67 | }
68 | export default config;
69 |
--------------------------------------------------------------------------------
/misc/cyberbox/metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Link3 Mystery Box",
3 | "description": "Mystery Box is a mysterious and secret benefit designed to reward early Link3 adopters who're actively helping us build the layer of trust.",
4 | "image": "ipfs://QmVKQUCW4yb8YvJpVDs2gQLWNEJaQk5BD74Kb7jcGwBdQE",
5 | "animation_url": "ipfs://QmVKQUCW4yb8YvJpVDs2gQLWNEJaQk5BD74Kb7jcGwBdQE",
6 | "external_url": "https://link3.to",
7 | "attributes": [
8 | ]
9 | }
--------------------------------------------------------------------------------
/misc/post_deploy.ts:
--------------------------------------------------------------------------------
1 | import * as fs from "fs/promises";
2 | import * as path from "path";
3 |
4 | const writeAbi = async () => {
5 | const folders = [
6 | "RolesAuthority.sol/RolesAuthority.json",
7 | "CyberEngine.sol/CyberEngine.json",
8 | "EssenceNFT.sol/EssenceNFT.json",
9 | "ProfileNFT.sol/ProfileNFT.json",
10 | "SubscribeNFT.sol/SubscribeNFT.json",
11 |
12 | "Link3ProfileDescriptor.sol/Link3ProfileDescriptor.json",
13 | "CyberBoxNFT.sol/CyberBoxNFT.json",
14 | "CyberGrandNFT.sol/CyberGrandNFT.json",
15 | "MBNFT.sol/MBNFT.json",
16 | "FrameNFT.sol/FrameNFT.json",
17 | "MiniShardNFT.sol/MiniShardNFT.json",
18 | "CyberVault.sol/CyberVault.json",
19 | "RelationshipChecker.sol/RelationshipChecker.json",
20 |
21 | "Treasury.sol/Treasury.json",
22 |
23 | "CollectDisallowedMw.sol/CollectDisallowedMw.json",
24 | "CollectMerkleDropMw.sol/CollectMerkleDropMw.json",
25 | "CollectOnlySubscribedMw.sol/CollectOnlySubscribedMw.json",
26 | "CollectPaidMw.sol/CollectPaidMw.json",
27 | "CollectPermissionMw.sol/CollectPermissionMw.json",
28 | "CollectLimitedTimePaidMw.sol/CollectLimitedTimePaidMw.json",
29 | "CollectPermissionPaidMw.sol/CollectPermissionPaidMw.json",
30 | "CollectFlexPaidMw.sol/CollectFlexPaidMw.json",
31 |
32 | "PermissionedFeeCreationMw.sol/PermissionedFeeCreationMw.json",
33 | "StableFeeCreationMw.sol/StableFeeCreationMw.json",
34 | "SubscribeDisallowedMw.sol/SubscribeDisallowedMw.json",
35 | "SubscribeOnlyOnceMw.sol/SubscribeOnlyOnceMw.json",
36 | "SubscribePaidMw.sol/SubscribePaidMw.json",
37 | ];
38 | const ps = folders.map(async (file) => {
39 | const f = await fs.readFile(path.join("./out", file), "utf8");
40 | const json = JSON.parse(f);
41 | const fileName = path.parse(file).name;
42 | return fs.writeFile(
43 | path.join("docs/abi", `${fileName}.json`),
44 | JSON.stringify(json.abi)
45 | );
46 | });
47 | await Promise.all(ps);
48 | };
49 |
50 | const main = async () => {
51 | await writeAbi();
52 | };
53 |
54 | main()
55 | .then(() => {})
56 | .catch((err) => {
57 | console.error(err);
58 | });
59 |
--------------------------------------------------------------------------------
/misc/pre_deploy.js:
--------------------------------------------------------------------------------
1 | import * as fsSync from "fs";
2 | import * as fs from "fs/promises";
3 | import * as dotenv from "dotenv";
4 | import * as path from "path";
5 | dotenv.config({ debug: true, path: ".env.rinkeby" });
6 |
7 | import { default as FormData } from "form-data";
8 | import axios from "axios";
9 |
10 | import { ethers } from "ethers";
11 |
12 | const pinataBase = "https://cyberconnect.mypinata.cloud/ipfs/";
13 | const pinataJWT = process.env.PINATA_JWT;
14 |
15 | const writeTemplate = async (profileProxy) => {
16 | const file = await fs.readFile(path.join("./template", "index.html"), "utf8");
17 | const out = file.replace(
18 | /0x000000000000000000000000000000000000DEAD/g,
19 | profileProxy
20 | );
21 | const dir = path.join("./docs/template");
22 | await fs.rm(dir, { recursive: true, force: true });
23 |
24 | const output = path.join(dir, "index.html");
25 | await fs.mkdir(dir, { recursive: true });
26 | await fs.writeFile(output, out);
27 | return { output, dir };
28 | };
29 | const writeToPinata = async ({ output, dir }) => {
30 | var data = new FormData();
31 | data.append("file", fsSync.createReadStream(output));
32 | data.append("pinataOptions", '{"cidVersion": 1}');
33 |
34 | const config = {
35 | method: "post",
36 | url: "https://api.pinata.cloud/pinning/pinFileToIPFS",
37 | headers: {
38 | Authorization: "Bearer " + pinataJWT,
39 | ...data.getHeaders(),
40 | },
41 | data: data,
42 | };
43 |
44 | const res = await axios(config);
45 | console.log(res.data);
46 |
47 | await fs.rename(output, path.join(dir, res.data.IpfsHash));
48 | return pinataBase + res.data.IpfsHash;
49 | };
50 |
51 | const calc = async () => {
52 | const provider = new ethers.providers.JsonRpcProvider(
53 | process.env.RINKEBY_RPC_URL
54 | );
55 | const deployer = new ethers.Wallet(process.env.PRIVATE_KEY);
56 |
57 | let deployerNonce = await provider.getTransactionCount(deployer.address);
58 | const profileProxyNonce = ethers.utils.hexlify(deployerNonce + 3);
59 | const profileProxyAddr =
60 | "0x" +
61 | ethers.utils
62 | .keccak256(ethers.utils.RLP.encode([deployer.address, profileProxyNonce]))
63 | .substr(26);
64 | return ethers.utils.getAddress(profileProxyAddr); // checksum
65 | };
66 |
67 | const templateDeployScript = async (profileProxy, templateURL) => {
68 | console.log(templateURL);
69 | const p = path.join("./template", "Deploy.s.sol.template");
70 | const outP = path.join("./script", "Deploy.s.sol");
71 | const file = await fs.readFile(p, "utf8");
72 | let out = file.replace(/0xDEAD/g, profileProxy);
73 | out = out.replace(/TEMPLATE_URL/g, templateURL);
74 | await fs.writeFile(outP, out);
75 | };
76 |
77 | const main = async () => {
78 | const profileProxy = await calc();
79 | const out = await writeTemplate(profileProxy);
80 | const pinataURL = await writeToPinata(out);
81 | console.log("profileProxy", profileProxy);
82 | await templateDeployScript(profileProxy, pinataURL);
83 | };
84 |
85 | main()
86 | .then(() => {})
87 | .catch((err) => {
88 | console.error(err);
89 | });
90 |
--------------------------------------------------------------------------------
/misc/qrcode/QRSVG.t.sol.template:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Test.sol";
6 | import { QRSVG } from "../../src/libraries/QRSVG.sol";
7 | import "forge-std/console.sol";
8 |
9 | contract QRSVGIntegrationTest is Test {
10 | string[] names = NAMES;
11 | string[] urls = URLS;
12 |
13 | function testGenerateQR() public {
14 | assert(names.length == urls.length);
15 | for (uint256 i = 0; i < names.length; i++) {
16 | string memory name = names[i];
17 | string memory url = urls[i];
18 | string memory code = QRSVG.generateQRCode(url);
19 | vm.writeFile(
20 | string(abi.encodePacked("./misc/qrcode/svg/", name)),
21 | code
22 | );
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/misc/qrcode/gen-html.js:
--------------------------------------------------------------------------------
1 | import * as fs from "fs/promises";
2 | import * as path from "path";
3 | const dir = path.join("./misc/qrcode/html/");
4 |
5 | const writeTemplate = async (url, content) => {
6 | const file = await fs.readFile(
7 | path.join("./misc/qrcode/", "qr-test.html.template"),
8 | "utf8"
9 | );
10 | const out = file.replace(/REPLACE_ME/g, content);
11 |
12 | const output = path.join(dir, `${url}.html`);
13 | await fs.mkdir(dir, { recursive: true });
14 | await fs.writeFile(output, out);
15 | return { output, dir };
16 | };
17 |
18 | const p = "./misc/qrcode/svg";
19 |
20 | const main = async () => {
21 | try {
22 | const exists = await fs.access(dir, 0);
23 | if (exists) {
24 | await fs.rm(dir, { recursive: true, force: true });
25 | }
26 | } catch (err) {}
27 | const files = await fs.readdir(p);
28 | console.log("total tests:", files.length);
29 | // console.log(files);
30 | const all = [];
31 | const a = async (aa) => {
32 | const content = await fs.readFile(path.join(p, aa));
33 | return writeTemplate(aa, content);
34 | };
35 | for (let i = 0; i < files.length; i++) {
36 | all.push(a(files[i]));
37 | }
38 | return Promise.all(all);
39 | };
40 |
41 | main()
42 | .then(() => {})
43 | .catch((err) => {
44 | console.error(err);
45 | });
46 |
--------------------------------------------------------------------------------
/misc/qrcode/gen-sol.js:
--------------------------------------------------------------------------------
1 | import * as fs from "fs/promises";
2 | import * as path from "path";
3 | const writeTemplate = async (i, batch) => {
4 | const file = await fs.readFile(
5 | path.join("./misc/qrcode", "QRSVG.t.sol.template"),
6 | "utf8"
7 | );
8 | const urls = batch.map((str) => `https://link3.to/${str}`);
9 | let out = file.replace(/URLS/g, JSON.stringify(urls));
10 | out = out.replace(/NAMES/g, JSON.stringify(batch));
11 |
12 | const output = path.join(dir, `QRSVG-${i}-${batch.length}.t.sol`);
13 | await fs.mkdir(dir, { recursive: true });
14 | await fs.writeFile(output, out);
15 | return { output, dir };
16 | };
17 |
18 | const dir = path.join("./test/qrcode/");
19 |
20 | const main = async () => {
21 | try {
22 | const exists = await fs.access(dir, 0);
23 | if (exists) {
24 | await fs.rm(dir, { recursive: true, force: true });
25 | }
26 | } catch (err) {}
27 | const all = [];
28 | let batch = [];
29 | let counter = 0;
30 | const length = 27;
31 | const iteration = 100;
32 | let total = [];
33 | for (let j = 1; j <= length; j++) {
34 | // 27 is the max length of the link3 handle
35 | for (let i = 0; i < iteration; i++) {
36 | // how many tries for each length
37 | const str = randomString(j, wordlist);
38 | batch.push(str);
39 | if (batch.length == 40) {
40 | all.push(writeTemplate(counter, batch));
41 | total = total.concat(batch);
42 | batch = [];
43 | counter++;
44 | }
45 | }
46 | }
47 | if (batch) {
48 | all.push(writeTemplate(counter, batch));
49 | total = total.concat(batch);
50 | }
51 | const toFindDuplicates = (arry) =>
52 | arry.filter((item, index) => arry.indexOf(item) !== index);
53 | const duplicates = toFindDuplicates(total);
54 | console.log("random tests:", total.length);
55 | console.log("duplicate", duplicates.length);
56 | console.log("total unique tests", total.length - duplicates.length);
57 | return Promise.all(all);
58 | };
59 | function randomString(length, chars) {
60 | var result = "";
61 | for (var i = length; i > 0; --i)
62 | result += chars[Math.floor(Math.random() * chars.length)];
63 | return result;
64 | }
65 | const wordlist = "0123456789abcdefghijklmnopqrstuvwxyz_";
66 |
67 | main()
68 | .then(() => {})
69 | .catch((err) => {
70 | console.error(err);
71 | });
72 |
--------------------------------------------------------------------------------
/misc/qrcode/puppet.js:
--------------------------------------------------------------------------------
1 | import * as path from "path";
2 | import * as fs from "fs/promises";
3 | import { Cluster } from "puppeteer-cluster";
4 |
5 | (async () => {
6 | const cluster = await Cluster.launch({
7 | concurrency: Cluster.CONCURRENCY_CONTEXT,
8 | maxConcurrency: 20,
9 | // monitor: true,
10 | });
11 | const files = await fs.readdir("./misc/qrcode/html");
12 | console.log("total tests:", files.length);
13 | await cluster.task(async ({ page, data: url }) => {
14 | const file = path.parse(url).name;
15 | page.on("console", (msg) => {
16 | if (msg.text() !== "https://link3.to/" + file) {
17 | console.error(
18 | "====================wrong url. got, expected: ",
19 | msg.text(),
20 | file
21 | );
22 | } else {
23 | // console.log("Correct url:", msg.text());
24 | }
25 | });
26 | await page.goto(url);
27 | });
28 | for (let i = 0; i < files.length; i++) {
29 | const dirUrl = new URL(".", import.meta.url);
30 | const f = dirUrl.href + "html/" + files[i];
31 | cluster.queue(f);
32 | }
33 |
34 | await cluster.idle();
35 | await cluster.close();
36 | })();
37 |
--------------------------------------------------------------------------------
/misc/qrcode/qr-test.html.template:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | QrcodeDecoder - Image
8 |
9 |
10 |
11 |
12 |
16 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/remappings.txt:
--------------------------------------------------------------------------------
1 | ds-test/=lib/forge-std/lib/ds-test/src/
2 | forge-std/=lib/forge-std/src/
3 | openzeppelin-contracts/=lib/openzeppelin-contracts/
4 | chainlink/=lib/chainlink/
5 |
--------------------------------------------------------------------------------
/script/AllowCurrency.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { DeploySetting } from "./libraries/DeploySetting.sol";
7 | import { LibDeploy } from "./libraries/LibDeploy.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 | vm.startBroadcast();
13 |
14 | if (block.chainid == DeploySetting.GOERLI) {
15 | LibDeploy.allowCurrency(
16 | vm,
17 | address(0x3963744012daDf90A9034Ea1068f53108B1A3834), // Treasury Address
18 | address(0x326C977E6efc84E512bB9C30f76E30c160eD06FB) // Currency Address
19 | );
20 | } else if (block.chainid == DeploySetting.BNB) {
21 | LibDeploy.allowCurrency(
22 | vm,
23 | address(0x90137F1234C137C4284dd317303F2717c871f70A), // Treasury Address
24 | address(0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56) // Currency Address
25 | );
26 | }
27 | vm.stopBroadcast();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/script/Deploy.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { LibDeploy } from "./libraries/LibDeploy.sol";
7 | import { DeploySetting } from "./libraries/DeploySetting.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 |
13 | vm.startBroadcast();
14 |
15 | LibDeploy.deploy(
16 | vm,
17 | LibDeploy.DeployParams(true, true, deployParams),
18 | deployParams.link3Signer // mint test profile to signer
19 | );
20 |
21 | vm.stopBroadcast();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/script/DeployAction.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { DeploySetting } from "./libraries/DeploySetting.sol";
7 | import { LibDeploy } from "./libraries/LibDeploy.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 | vm.startBroadcast();
13 | LibDeploy.deployActionLib(vm, deployParams.deployerContract, true);
14 | vm.stopBroadcast();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/script/DeployBox.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { DeploySetting } from "./libraries/DeploySetting.sol";
7 | import { LibDeploy } from "./libraries/LibDeploy.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 | vm.startBroadcast();
13 | if (block.chainid == DeploySetting.MAINNET) {
14 | LibDeploy.deployBox(
15 | vm,
16 | deployParams.deployerContract,
17 | deployParams.link3Owner,
18 | deployParams.link3Owner, // owner address
19 | true
20 | );
21 | } else if (block.chainid == DeploySetting.BNBT) {
22 | LibDeploy.deployBox(
23 | vm,
24 | deployParams.deployerContract,
25 | deployParams.link3Signer,
26 | deployParams.link3Owner, // owner address
27 | true
28 | );
29 | } else if (block.chainid == DeploySetting.BNB) {
30 | LibDeploy.deployBox(
31 | vm,
32 | deployParams.deployerContract,
33 | deployParams.link3Signer,
34 | address(0xf9E12df9428F1a15BC6CfD4092ADdD683738cE96), // owner address - safe
35 | true
36 | );
37 | }
38 |
39 | vm.stopBroadcast();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/script/DeployChecker.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { DeploySetting } from "./libraries/DeploySetting.sol";
7 | import { LibDeploy } from "./libraries/LibDeploy.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 | vm.startBroadcast();
13 |
14 | if (block.chainid == DeploySetting.GOERLI) {
15 | LibDeploy.deployRelationshipChecker(
16 | vm,
17 | LibDeploy.DeployParams(true, true, deployParams),
18 | address(0x57e12b7a5F38A7F9c23eBD0400e6E53F2a45F271), // link3 namespace
19 | true
20 | );
21 | } else if (block.chainid == DeploySetting.BNBT) {
22 | LibDeploy.deployRelationshipChecker(
23 | vm,
24 | LibDeploy.DeployParams(true, true, deployParams),
25 | address(0x57e12b7a5F38A7F9c23eBD0400e6E53F2a45F271), // link3 namespace
26 | true
27 | );
28 | } else if (block.chainid == DeploySetting.BNB) {
29 | LibDeploy.deployRelationshipChecker(
30 | vm,
31 | LibDeploy.DeployParams(true, true, deployParams),
32 | address(0x2723522702093601e6360CAe665518C4f63e9dA6), // link3 namespace
33 | true
34 | );
35 | }
36 | vm.stopBroadcast();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/script/DeployCreate2Deployer.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity ^0.8.13;
4 |
5 | import "forge-std/Script.sol";
6 | import "../src/deployer/Create2Deployer.sol";
7 |
8 | contract DeployerCreate2Deployer is Script {
9 | function run() external {
10 | uint256 nonce = vm.getNonce(msg.sender);
11 | if (block.chainid == 1 || block.chainid == 42170) {
12 | require(nonce == 0, "nonce must be 0");
13 | console.log("deployer", msg.sender);
14 | require(
15 | msg.sender == 0xA7b6bEf855c1c57Df5b7C9c7a4e1eB757e544e7f,
16 | "address must be deployer"
17 | );
18 | }
19 |
20 | vm.startBroadcast();
21 | new Create2Deployer();
22 | vm.stopBroadcast();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/script/DeployCyberToken.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { DeploySetting } from "./libraries/DeploySetting.sol";
7 | import { LibDeploy } from "./libraries/LibDeploy.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 | vm.startBroadcast();
13 | LibDeploy.deployCyberToken(
14 | vm,
15 | deployParams.cyberTokenOwner,
16 | deployParams.cyberTokenOwner,
17 | true
18 | );
19 | vm.stopBroadcast();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/script/DeployFrame.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { DeploySetting } from "./libraries/DeploySetting.sol";
7 | import { LibDeploy } from "./libraries/LibDeploy.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 | vm.startBroadcast();
13 |
14 | if (block.chainid == DeploySetting.GOERLI) {
15 | LibDeploy.deployFrame(
16 | vm,
17 | deployParams.deployerContract,
18 | deployParams.link3Signer,
19 | true
20 | );
21 | } else if (block.chainid == POLYGON) {
22 | LibDeploy.deployFrame(
23 | vm,
24 | deployParams.deployerContract,
25 | deployParams.link3Signer,
26 | true
27 | );
28 | }
29 | vm.stopBroadcast();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/script/DeployGrand.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { DeploySetting } from "./libraries/DeploySetting.sol";
7 | import { LibDeploy } from "./libraries/LibDeploy.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 | vm.startBroadcast();
13 | LibDeploy.deployGrand(
14 | vm,
15 | deployParams.deployerContract,
16 | deployParams.link3Owner,
17 | deployParams.link3Signer,
18 | true
19 | );
20 | vm.stopBroadcast();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/script/DeployMB.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { DeploySetting } from "./libraries/DeploySetting.sol";
7 | import { LibDeploy } from "./libraries/LibDeploy.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 | vm.startBroadcast();
13 |
14 | if (block.chainid == DeploySetting.GOERLI) {
15 | LibDeploy.deployMB(
16 | vm,
17 | deployParams.deployerContract,
18 | deployParams.link3Owner,
19 | address(0x1cC24A44c4b51D3F9B0d0F5BdCF95b0F385B154f),
20 | "https://mb-metadata.cyberconnect.dev",
21 | true
22 | );
23 | } else if (block.chainid == DeploySetting.MAINNET) {
24 | LibDeploy.deployMB(
25 | vm,
26 | deployParams.deployerContract,
27 | deployParams.link3Owner,
28 | address(0xcE4F341622340d56E397740d325Fd357E62b91CB),
29 | "https://mbmetadata.cyberconnect.dev",
30 | true
31 | );
32 | } else if (block.chainid == DeploySetting.BNB) {
33 | LibDeploy.deployMB(
34 | vm,
35 | deployParams.deployerContract,
36 | address(0xf9E12df9428F1a15BC6CfD4092ADdD683738cE96), // owner address - safe
37 | address(0xCAdC6C364E8fcad0F382FDdfd6ff5b41d82EB3e4),
38 | "https://mbmetadata.cyberconnect.dev/bnb",
39 | true
40 | );
41 | } else if (block.chainid == DeploySetting.BNBT) {
42 | LibDeploy.deployMB(
43 | vm,
44 | deployParams.deployerContract,
45 | deployParams.link3Owner,
46 | address(0x54346edD22ef49bdcA1aaE6114F8B1a1E598b674),
47 | "https://mb-metadata.cyberconnect.dev/bnb",
48 | true
49 | );
50 | }
51 | vm.stopBroadcast();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/script/DeployMiddleware.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { DeploySetting } from "./libraries/DeploySetting.sol";
7 | import { LibDeploy } from "./libraries/LibDeploy.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 | vm.startBroadcast();
13 | if (block.chainid == DeploySetting.BNBT) {
14 | LibDeploy.deployAllMiddleware(
15 | vm,
16 | LibDeploy.DeployParams(true, true, deployParams),
17 | address(0xAF9104Eb9c6B21Efdc43BaaaeE70662d6CcE8798), // engine proxy address
18 | address(0x3963744012daDf90A9034Ea1068f53108B1A3834), // cyber treasury address
19 | address(0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e), // bnb-usd oracle address
20 | address(0x57e12b7a5F38A7F9c23eBD0400e6E53F2a45F271), // namespace
21 | true
22 | );
23 | } else if (block.chainid == DeploySetting.BNB) {
24 | LibDeploy.deployAllMiddleware(
25 | vm,
26 | LibDeploy.DeployParams(true, true, deployParams),
27 | address(0x1cA51941a616D14C42D3e3B9E6E687d7F5054c3A), // engine proxy address
28 | address(0x90137F1234C137C4284dd317303F2717c871f70A), // cyber treasury address
29 | address(0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE), // bnb-usd oracle address
30 | address(0x2723522702093601e6360CAe665518C4f63e9dA6), // namespace
31 | true
32 | );
33 | }
34 | vm.stopBroadcast();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/script/DeployMiniShard.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { DeploySetting } from "./libraries/DeploySetting.sol";
7 | import { LibDeploy } from "./libraries/LibDeploy.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 | vm.startBroadcast();
13 |
14 | if (block.chainid == DeploySetting.BNBT) {
15 | LibDeploy.deployMiniShard(
16 | vm,
17 | deployParams.deployerContract,
18 | deployParams.link3Signer,
19 | "https://mb-metadata.cyberconnect.dev/minishards",
20 | true
21 | );
22 | } else if (block.chainid == BNB) {
23 | LibDeploy.deployMiniShard(
24 | vm,
25 | deployParams.deployerContract,
26 | deployParams.link3Signer,
27 | "https://mbmetadata.cyberconnect.dev/minishards",
28 | true
29 | );
30 | } else if (block.chainid == POLYGON) {
31 | LibDeploy.deployMiniShard(
32 | vm,
33 | deployParams.deployerContract,
34 | deployParams.link3Signer,
35 | "https://mbmetadata.cyberconnect.dev/minishards-polygon",
36 | true
37 | );
38 | }
39 | vm.stopBroadcast();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/script/DeployNamespace.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { DeploySetting } from "./libraries/DeploySetting.sol";
7 | import { LibDeploy } from "./libraries/LibDeploy.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | string internal constant CYBERCONNECT_NAME = "CyberConnect";
11 | string internal constant CYBERCONNECT_SYMBOL = "CYBERCONNECT";
12 | bytes32 constant CYBERCONNECT_SALT = keccak256(bytes(CYBERCONNECT_NAME));
13 |
14 | function run() external {
15 | _setDeployParams();
16 | vm.startBroadcast();
17 | address profileAddr;
18 | if (
19 | block.chainid == DeploySetting.BNBT ||
20 | block.chainid == DeploySetting.GOERLI
21 | ) {
22 | (profileAddr, , ) = LibDeploy.createNamespace(
23 | address(0xAF9104Eb9c6B21Efdc43BaaaeE70662d6CcE8798), // engine proxy address
24 | address(0x927f355117721e0E8A7b5eA20002b65B8a551890), // link3Owner
25 | CYBERCONNECT_NAME, // LINK3_NAME,
26 | CYBERCONNECT_SYMBOL, // LINK3_SYMBOL,
27 | CYBERCONNECT_SALT, // LINK3_SALT,
28 | address(0x27361075Ea6E85564a4B00F5828235FC4C8C2e32), // addrs.profileFac,
29 | address(0x958d142Ef3a7B2ee34CDF1F81C135FB91a454A5C), // addrs.subFac,
30 | address(0x216BA81b5FD81253FDE6888039c6001D6f891eFb) // addrs.essFac
31 | );
32 | }
33 |
34 | console.log("CyberConnect Profile:", profileAddr);
35 | vm.stopBroadcast();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/script/DeployPermissionless.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { DeployNamespace } from "./libraries/DeployNamespace.sol";
7 | import { DeploySetting } from "./libraries/DeploySetting.sol";
8 |
9 | contract DeployPermissionlessScript is Script {
10 | DeployNamespace.DeployNamespaceParams params;
11 |
12 | function _setup() private {
13 | if (block.chainid == 5) {
14 | params.engineProxy = 0xadAEc1655D34c9E86394400e1cdEF3BaC3F0C117;
15 | params.namespaceOwner = 0x927f355117721e0E8A7b5eA20002b65B8a551890;
16 | params.name = "CyberConnect";
17 | params.symbol = "CYBER";
18 | params.profileFac = 0x5eB4f4d2b4A2C0E331e1c1767143EfcB91Bf56e7;
19 | params.subFac = 0xa97a8F309263658B77a2755be861173fB633020d;
20 | params.essFac = 0xcfB865f5F4a3c74cc2CAC0460273BB43f3D8E27C;
21 | }
22 | }
23 |
24 | function run() external {
25 | _setup();
26 | vm.startBroadcast();
27 |
28 | DeployNamespace.deployNamespace(vm, params);
29 | vm.stopBroadcast();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/script/DeployTimeLock.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { DeploySetting } from "./libraries/DeploySetting.sol";
7 | import { LibDeploy } from "./libraries/LibDeploy.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 | vm.startBroadcast();
13 |
14 | if (block.chainid == 5) {
15 | address timelock = LibDeploy.deployTimeLock(
16 | vm,
17 | deployParams.link3Owner,
18 | 600,
19 | true
20 | );
21 | LibDeploy.changeOwnership(
22 | vm,
23 | timelock,
24 | deployParams.engineGov,
25 | address(0x12F7bBc1A79ECA365F9A833a298E6684458F93bF), // role auth
26 | address(0x1Dfc23a9A81202980711A334B07038A9A1789d73), // box proxy
27 | address(0x994d90C72aD3eeB327b6f6288D544384eF53a020), // desc proxy
28 | address(0xB9d6D688E1e051CB74E5B5d1627421De56F2B4aD) // treasury proxy
29 | );
30 | } else if (block.chainid == 1) {
31 | address timelock = LibDeploy.deployTimeLock(
32 | vm,
33 | deployParams.cyberTokenOwner,
34 | 48 * 3600,
35 | true
36 | );
37 | LibDeploy.changeOwnership(
38 | vm,
39 | timelock,
40 | deployParams.engineGov,
41 | address(0x5cf03F4997AFa9A94506990D24c12D6aBaD61E6F), // role auth
42 | address(0xcE4F341622340d56E397740d325Fd357E62b91CB), // box proxy
43 | address(0x818CBEE6081ae4C89caBc642Ac2542b2585F68Bb), // desc proxy
44 | address(0x5DA0eD64A9868d128F8d6f56dC78B727F85ff2D0) // treasury proxy
45 | );
46 | }
47 | vm.stopBroadcast();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/script/DeployVault.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { DeploySetting } from "./libraries/DeploySetting.sol";
7 | import { LibDeploy } from "./libraries/LibDeploy.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 | vm.startBroadcast();
13 | LibDeploy.deployVault(
14 | vm,
15 | LibDeploy.DeployParams(true, true, deployParams),
16 | deployParams.link3Signer,
17 | true
18 | );
19 | vm.stopBroadcast();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/script/RegisterProfile.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { DeploySetting } from "./libraries/DeploySetting.sol";
7 | import { LibDeploy } from "./libraries/LibDeploy.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 | vm.startBroadcast();
13 |
14 | LibDeploy.DeployParams memory params = LibDeploy.DeployParams(
15 | true,
16 | true,
17 | deployParams
18 | );
19 |
20 | if (block.chainid == 97) {
21 | LibDeploy.registerLink3TestProfile(
22 | vm,
23 | LibDeploy.RegisterLink3TestProfileParams(
24 | address(0xc633795bE5E61F0363e239fC21cF32dbB073Fd21), // profile
25 | address(0x7294aB1F2C1601c3da46499574e16078a42c8056), // engine
26 | address(0x342456d340D705f6B58137b57bEbEAd0069ba646), // profile mw
27 | address(0x927f355117721e0E8A7b5eA20002b65B8a551890), // toEOA
28 | params.setting.link3Treasury,
29 | params.setting.engineTreasury
30 | )
31 | );
32 | } else if (block.chainid == 5) {
33 | LibDeploy.registerLink3TestProfile(
34 | vm,
35 | LibDeploy.RegisterLink3TestProfileParams(
36 | address(0x7B2bc3ae8f816a431Ff438d939C44E1A502EaD25),
37 | address(0x47C282Bef1dE396Defd13878859B580636b81796),
38 | address(0x8a07C56c28FC62CAC8F42fdD1F16f0cE3141c291),
39 | address(0x927f355117721e0E8A7b5eA20002b65B8a551890),
40 | params.setting.link3Treasury,
41 | params.setting.engineTreasury
42 | )
43 | );
44 | }
45 | vm.stopBroadcast();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/script/SetAniURL.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { LibDeploy } from "./libraries/LibDeploy.sol";
7 | import { DeploySetting } from "./libraries/DeploySetting.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 |
13 | vm.startBroadcast();
14 | if (block.chainid == DeploySetting.MAINNET) {
15 | LibDeploy.setAniURL(
16 | vm,
17 | LibDeploy.DeployParams(true, true, deployParams),
18 | address(0x818CBEE6081ae4C89caBc642Ac2542b2585F68Bb) // link3 descriptor
19 | );
20 | }
21 |
22 | vm.stopBroadcast();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/script/SetAnimationURLV3.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { LibDeploy } from "./libraries/LibDeploy.sol";
7 | import { DeploySetting } from "./libraries/DeploySetting.sol";
8 |
9 | contract SetAnimationURLV3 is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 | vm.startBroadcast();
13 |
14 | if (block.chainid == DeploySetting.MAINNET) {
15 | LibDeploy.deployLink3DescriptorV3(
16 | vm,
17 | deployParams.deployerContract,
18 | true,
19 | address(0x8CC6517e45dB7a0803feF220D9b577326A12033f), // link3Profile
20 | deployParams.link3Owner
21 | );
22 | } else if (block.chainid == DeploySetting.BNBT) {
23 | LibDeploy.deployLink3DescriptorV3(
24 | vm,
25 | deployParams.deployerContract,
26 | true,
27 | address(0x57e12b7a5F38A7F9c23eBD0400e6E53F2a45F271), // link3Profile
28 | deployParams.link3Owner
29 | );
30 | } else if (block.chainid == DeploySetting.BNB) {
31 | LibDeploy.deployLink3DescriptorV3(
32 | vm,
33 | deployParams.deployerContract,
34 | true,
35 | address(0x2723522702093601e6360CAe665518C4f63e9dA6), // link3Profile
36 | deployParams.link3Owner
37 | );
38 | }
39 |
40 | vm.stopBroadcast();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/script/SetFeeCreationMw.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { LibDeploy } from "./libraries/LibDeploy.sol";
7 | import { DeploySetting } from "./libraries/DeploySetting.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 |
13 | vm.startBroadcast();
14 |
15 | if (block.chainid == DeploySetting.GOERLI) {
16 | LibDeploy.setFeeCreationMw(
17 | vm,
18 | LibDeploy.DeployParams(true, true, deployParams),
19 | address(0xAF9104Eb9c6B21Efdc43BaaaeE70662d6CcE8798), //engineProxyAddress,
20 | address(0x57e12b7a5F38A7F9c23eBD0400e6E53F2a45F271), //address link3Profile,
21 | address(0xf1D8512d08F3924768041d1063Ef5517Ca867f0d) //address feeCreationMw
22 | );
23 | } else if (block.chainid == DeploySetting.BNB) {
24 | LibDeploy.setFeeCreationMw(
25 | vm,
26 | LibDeploy.DeployParams(true, true, deployParams),
27 | address(0x1cA51941a616D14C42D3e3B9E6E687d7F5054c3A), //engineProxyAddress,
28 | address(0x2723522702093601e6360CAe665518C4f63e9dA6), //address link3Profile,
29 | address(0xE072666997B472a908e45B4B73B430dfBA9F6d33) //address feeCreationMw
30 | );
31 | } else if (block.chainid == DeploySetting.BNBT) {
32 | LibDeploy.setFeeCreationMw(
33 | vm,
34 | LibDeploy.DeployParams(true, true, deployParams),
35 | address(0xAF9104Eb9c6B21Efdc43BaaaeE70662d6CcE8798), //engineProxyAddress,
36 | address(0x57e12b7a5F38A7F9c23eBD0400e6E53F2a45F271), //address link3Profile,
37 | address(0x708e5a5Ad95520fA8fddCE8F8C86b095723E32CF) //address feeCreationMw
38 | );
39 | }
40 |
41 | vm.stopBroadcast();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/script/SetProfileMw.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { LibDeploy } from "./libraries/LibDeploy.sol";
7 | import { DeploySetting } from "./libraries/DeploySetting.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 |
13 | vm.startBroadcast();
14 |
15 | if (
16 | block.chainid == DeploySetting.BNBT ||
17 | block.chainid == DeploySetting.GOERLI
18 | ) {
19 | LibDeploy.setProfileMw(
20 | vm,
21 | LibDeploy.DeployParams(true, true, deployParams),
22 | address(0xAF9104Eb9c6B21Efdc43BaaaeE70662d6CcE8798), //engineProxyAddress,
23 | address(0x57e12b7a5F38A7F9c23eBD0400e6E53F2a45F271), //address link3Profile,
24 | address(0) //address link3ProfileMw
25 | );
26 | } else if (
27 | block.chainid == DeploySetting.BNB ||
28 | block.chainid == DeploySetting.NOVA
29 | ) {
30 | LibDeploy.setProfileMw(
31 | vm,
32 | LibDeploy.DeployParams(true, true, deployParams),
33 | address(0x1cA51941a616D14C42D3e3B9E6E687d7F5054c3A), //engineProxyAddress,
34 | address(0x2723522702093601e6360CAe665518C4f63e9dA6), //address link3Profile,
35 | address(0xd37bbF27e39B2f8c4386BebcCdA0850EEfFD2a82) //address link3ProfileMw
36 | );
37 | } else if (block.chainid == DeploySetting.POLYGON) {
38 | LibDeploy.setProfileMw(
39 | vm,
40 | LibDeploy.DeployParams(true, true, deployParams),
41 | address(0x64E1503a2419966c51332d7f6018dE9544AD78a1), //engineProxyAddress,
42 | address(0xbF029d040e3E6DA7b768b759dD9D67D84c73C06f), //address link3Profile,
43 | address(0x8323FFc73C027D8bEA4adb255447d3F5A8B3Ad12) //address link3ProfileMw
44 | );
45 | }
46 |
47 | vm.stopBroadcast();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/script/SetSigner.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { ProfileNFT } from "../src/core/ProfileNFT.sol";
7 | import { CyberEngine } from "../src/core/CyberEngine.sol";
8 | import { Link3ProfileDescriptor } from "../src/periphery/Link3ProfileDescriptor.sol";
9 | import { RolesAuthority } from "../src/dependencies/solmate/RolesAuthority.sol";
10 | import { LibDeploy } from "./libraries/LibDeploy.sol";
11 | import { PermissionedFeeCreationMw } from "../src/middlewares/profile/PermissionedFeeCreationMw.sol";
12 |
13 | contract DeployScript is Script {
14 | function run() external {
15 | vm.startBroadcast();
16 | // address link3Desc = 0x3B131D2d6694a60eb71dfF607cc64E6296daa71E;
17 | // address preOwner = 0x39e0c6E610A8D7F408dD688011591583cbc1c3ce;
18 | // address newOwner = 0xf9E12df9428F1a15BC6CfD4092ADdD683738cE96;
19 |
20 | // require(Link3ProfileDescriptor(link3Desc).owner() == preOwner, "WRONG_OWNER");
21 | // Link3ProfileDescriptor(link3Desc).setOwner(newOwner);
22 | // require(Link3ProfileDescriptor(link3Desc).owner() == newOwner, "WRONG_NEW_OWNER");
23 |
24 | // address roleAuth = 0x9937fb8ebe4Ebc7710fFAEd246584603F390BE3E;
25 | // address preOwner = 0xA7b6bEf855c1c57Df5b7C9c7a4e1eB757e544e7f;
26 | // address newOwner = 0xf9E12df9428F1a15BC6CfD4092ADdD683738cE96;
27 |
28 | // require(RolesAuthority(roleAuth).owner() == preOwner, "WRONG_OWNER");
29 | // RolesAuthority(roleAuth).setOwner(newOwner);
30 | // require(
31 | // RolesAuthority(roleAuth).owner() == newOwner,
32 | // "WRONG_NEW_OWNER"
33 | // );
34 |
35 | address link3Profile = 0x2723522702093601e6360CAe665518C4f63e9dA6;
36 | address preOwner = 0x39e0c6E610A8D7F408dD688011591583cbc1c3ce;
37 | address newOwner = 0xf9E12df9428F1a15BC6CfD4092ADdD683738cE96;
38 |
39 | require(
40 | ProfileNFT(link3Profile).getNamespaceOwner() == preOwner,
41 | "WRONG_NS_OWNER"
42 | );
43 | ProfileNFT(link3Profile).setNamespaceOwner(newOwner);
44 | require(
45 | ProfileNFT(link3Profile).getNamespaceOwner() == newOwner,
46 | "WRONG_NEW_OWNER"
47 | );
48 |
49 | vm.stopBroadcast();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/script/SetStableFeeMw.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { LibDeploy } from "./libraries/LibDeploy.sol";
7 | import { DeploySetting } from "./libraries/DeploySetting.sol";
8 |
9 | contract DeployScript is Script, DeploySetting {
10 | function run() external {
11 | _setDeployParams();
12 |
13 | vm.startBroadcast();
14 |
15 | if (block.chainid == DeploySetting.GOERLI) {
16 | LibDeploy.setStableFeeMw(
17 | vm,
18 | LibDeploy.DeployParams(true, true, deployParams),
19 | address(0xAF9104Eb9c6B21Efdc43BaaaeE70662d6CcE8798), //engineProxyAddress,
20 | address(0x57e12b7a5F38A7F9c23eBD0400e6E53F2a45F271), //address link3Profile,
21 | address(0x940d11e9105d7C0FFEE91E5e6B2375E3A58ec18A) //address stableFeeMw
22 | );
23 | } else if (block.chainid == DeploySetting.BNB) {
24 | LibDeploy.setStableFeeMw(
25 | vm,
26 | LibDeploy.DeployParams(true, true, deployParams),
27 | address(0x1cA51941a616D14C42D3e3B9E6E687d7F5054c3A), //engineProxyAddress,
28 | address(0x2723522702093601e6360CAe665518C4f63e9dA6), //address link3Profile,
29 | address(0x74bB8cb35f2187285319c60974CB278361940B30) //address stableFeeMw
30 | );
31 | } else if (block.chainid == DeploySetting.BNBT) {
32 | LibDeploy.setStableFeeMw(
33 | vm,
34 | LibDeploy.DeployParams(true, true, deployParams),
35 | address(0xAF9104Eb9c6B21Efdc43BaaaeE70662d6CcE8798), //engineProxyAddress,
36 | address(0x57e12b7a5F38A7F9c23eBD0400e6E53F2a45F271), //address link3Profile,
37 | address(0) //address stableFeeMw
38 | );
39 | } else if (block.chainid == DeploySetting.MAINNET) {
40 | LibDeploy.setStableFeeMw(
41 | vm,
42 | LibDeploy.DeployParams(true, true, deployParams),
43 | address(0xE8805326f9DA84e70c680429eD46B924b3F158F2), //engineProxyAddress,
44 | address(0x8CC6517e45dB7a0803feF220D9b577326A12033f), //address link3Profile,
45 | address(0x4C4bfA07bd28D1817D90E63a088643956f248159) //address stableFeeMw
46 | );
47 | } else if (block.chainid == DeploySetting.POLYGON) {
48 | LibDeploy.setStableFeeMw(
49 | vm,
50 | LibDeploy.DeployParams(true, true, deployParams),
51 | address(0x64E1503a2419966c51332d7f6018dE9544AD78a1), //engineProxyAddress,
52 | address(0xbF029d040e3E6DA7b768b759dD9D67D84c73C06f), //address link3Profile,
53 | address(0x45C3D3dC105Ba805E610f7fc2F3b4Ca5E29097a7) //address stableFeeMw
54 | );
55 | }
56 |
57 | vm.stopBroadcast();
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/script/Tmp.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { ProfileNFT } from "../src/core/ProfileNFT.sol";
7 | import { CyberEngine } from "../src/core/CyberEngine.sol";
8 | import { LibDeploy } from "./libraries/LibDeploy.sol";
9 | import { PermissionedFeeCreationMw } from "../src/middlewares/profile/PermissionedFeeCreationMw.sol";
10 |
11 | contract TempScript is Script {
12 | function run() external {
13 | address engineProxy = address(
14 | 0xE8805326f9DA84e70c680429eD46B924b3F158F2
15 | );
16 | address link3Profile = address(
17 | 0x8CC6517e45dB7a0803feF220D9b577326A12033f
18 | );
19 | console.log(
20 | CyberEngine(engineProxy).getProfileMwByNamespace((link3Profile))
21 | );
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/script/animation_url/anvil-31337/SetAnimationURL.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { ProfileNFT } from "../../../src/core/ProfileNFT.sol";
7 | import { Link3ProfileDescriptor } from "../../../src/periphery/Link3ProfileDescriptor.sol";
8 | import { Create2Deployer } from "../../../src/deployer/Create2Deployer.sol";
9 | import { LibDeploy } from "../../libraries/LibDeploy.sol";
10 | import { DeploySetting } from "../../libraries/DeploySetting.sol";
11 |
12 | contract SetAnimationURL is Script, DeploySetting {
13 | address internal link3Profile = 0x84009d423898B1c371b4515fa6540A922fF5e40a;
14 | string internal animationUrl =
15 | "https://cyberconnect.mypinata.cloud/ipfs/bafkreifjwei5tuvh5zjk7r6ti4wt7eon7dwnobchdinfmdzqhl2l2lrgve";
16 |
17 | function run() external {
18 | _setDeployParams();
19 | // make sure only on anvil
20 | address deployerContract = 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512;
21 | require(block.chainid == 31337, "ONLY_ANVIL");
22 | vm.startBroadcast();
23 |
24 | LibDeploy.deployLink3Descriptor(
25 | vm,
26 | deployerContract,
27 | true,
28 | animationUrl,
29 | link3Profile,
30 | deployParams.link3Owner
31 | );
32 |
33 | vm.stopBroadcast();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/script/animation_url/anvil-31337/SetAnimationURL.s.sol.template:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { ProfileNFT } from "../../../src/core/ProfileNFT.sol";
7 | import { Link3ProfileDescriptor } from "../../../src/periphery/Link3ProfileDescriptor.sol";
8 | import { Create2Deployer } from "../../../src/deployer/Create2Deployer.sol";
9 | import { LibDeploy } from "../../libraries/LibDeploy.sol";
10 | import { DeploySetting } from "../../libraries/DeploySetting.sol";
11 |
12 | contract SetAnimationURL is Script, DeploySetting {
13 | address internal link3Profile = LINK3_PROFILE;
14 | string internal animationUrl = "ANIMATION_URL";
15 |
16 | function run() external {
17 | _setDeployParams();
18 | // make sure only on anvil
19 | address deployerContract = 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512;
20 | require(block.chainid == 31337, "ONLY_ANVIL");
21 | vm.startBroadcast();
22 |
23 | LibDeploy.deployLink3Descriptor(
24 | vm,
25 | deployerContract,
26 | true,
27 | animationUrl,
28 | link3Profile,
29 | deployParams.link3Owner
30 | );
31 |
32 | vm.stopBroadcast();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/script/animation_url/bnb-56/SetAnimationURL.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { ProfileNFT } from "../../../src/core/ProfileNFT.sol";
7 | import { Link3ProfileDescriptor } from "../../../src/periphery/Link3ProfileDescriptor.sol";
8 | import { Create2Deployer } from "../../../src/deployer/Create2Deployer.sol";
9 | import { LibDeploy } from "../../libraries/LibDeploy.sol";
10 | import { DeploySetting } from "../../libraries/DeploySetting.sol";
11 |
12 | contract SetAnimationURL is Script, DeploySetting {
13 | address internal link3Profile = 0x2723522702093601e6360CAe665518C4f63e9dA6;
14 | string internal animationUrl =
15 | "https://cyberconnect.mypinata.cloud/ipfs/bafkreiblu7mqgd43bmenvsyfcp33pkrtjyc52ofwectc2257uicatn6vzm";
16 |
17 | function run() external {
18 | _setDeployParams();
19 | // make sure only on anvil
20 | require(block.chainid == 56, "ONLY_BNB");
21 | vm.startBroadcast();
22 |
23 | LibDeploy.deployLink3Descriptor(
24 | vm,
25 | deployParams.deployerContract,
26 | true,
27 | animationUrl,
28 | link3Profile,
29 | deployParams.link3Owner
30 | );
31 |
32 | vm.stopBroadcast();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/script/animation_url/bnb-56/SetAnimationURL.s.sol.template:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { ProfileNFT } from "../../../src/core/ProfileNFT.sol";
7 | import { Link3ProfileDescriptor } from "../../../src/periphery/Link3ProfileDescriptor.sol";
8 | import { Create2Deployer } from "../../../src/deployer/Create2Deployer.sol";
9 | import { LibDeploy } from "../../libraries/LibDeploy.sol";
10 | import { DeploySetting } from "../../libraries/DeploySetting.sol";
11 |
12 | contract SetAnimationURL is Script, DeploySetting {
13 | address internal link3Profile = LINK3_PROFILE;
14 | string internal animationUrl = "ANIMATION_URL";
15 |
16 | function run() external {
17 | _setDeployParams();
18 | // make sure only on anvil
19 | require(block.chainid == 56, "ONLY_BNB");
20 | vm.startBroadcast();
21 |
22 | LibDeploy.deployLink3Descriptor(
23 | vm,
24 | deployParams.deployerContract,
25 | true,
26 | animationUrl,
27 | link3Profile,
28 | deployParams.link3Owner
29 | );
30 |
31 | vm.stopBroadcast();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/script/animation_url/bnbt-97/SetAnimationURL.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { ProfileNFT } from "../../../src/core/ProfileNFT.sol";
7 | import { Link3ProfileDescriptor } from "../../../src/periphery/Link3ProfileDescriptor.sol";
8 | import { Create2Deployer } from "../../../src/deployer/Create2Deployer.sol";
9 | import { LibDeploy } from "../../libraries/LibDeploy.sol";
10 | import { DeploySetting } from "../../libraries/DeploySetting.sol";
11 |
12 | contract SetAnimationURL is Script, DeploySetting {
13 | address internal link3Profile = 0x57e12b7a5F38A7F9c23eBD0400e6E53F2a45F271;
14 | string internal animationUrl =
15 | "https://cyberconnect.mypinata.cloud/ipfs/bafkreigqqa3tkzqkl7bjylkya5nf5qsyyjcunsp4ix525icn5nycf7nw2m";
16 |
17 | function run() external {
18 | _setDeployParams();
19 | // make sure only on anvil
20 | require(block.chainid == 97, "ONLY_BNBT");
21 | vm.startBroadcast();
22 |
23 | LibDeploy.deployLink3Descriptor(
24 | vm,
25 | deployParams.deployerContract,
26 | true,
27 | animationUrl,
28 | link3Profile,
29 | deployParams.link3Owner
30 | );
31 |
32 | vm.stopBroadcast();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/script/animation_url/bnbt-97/SetAnimationURL.s.sol.template:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { ProfileNFT } from "../../../src/core/ProfileNFT.sol";
7 | import { Link3ProfileDescriptor } from "../../../src/periphery/Link3ProfileDescriptor.sol";
8 | import { Create2Deployer } from "../../../src/deployer/Create2Deployer.sol";
9 | import { LibDeploy } from "../../libraries/LibDeploy.sol";
10 | import { DeploySetting } from "../../libraries/DeploySetting.sol";
11 |
12 | contract SetAnimationURL is Script, DeploySetting {
13 | address internal link3Profile = LINK3_PROFILE;
14 | string internal animationUrl = "ANIMATION_URL";
15 |
16 | function run() external {
17 | _setDeployParams();
18 | // make sure only on anvil
19 | require(block.chainid == 97, "ONLY_BNBT");
20 | vm.startBroadcast();
21 |
22 | LibDeploy.deployLink3Descriptor(
23 | vm,
24 | deployParams.deployerContract,
25 | true,
26 | animationUrl,
27 | link3Profile,
28 | deployParams.link3Owner
29 | );
30 |
31 | vm.stopBroadcast();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/script/animation_url/goerli-5/SetAnimationURL.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { ProfileNFT } from "../../../src/core/ProfileNFT.sol";
7 | import { Link3ProfileDescriptor } from "../../../src/periphery/Link3ProfileDescriptor.sol";
8 | import { Create2Deployer } from "../../../src/deployer/Create2Deployer.sol";
9 | import { LibDeploy } from "../../libraries/LibDeploy.sol";
10 | import { DeploySetting } from "../../libraries/DeploySetting.sol";
11 |
12 | contract SetAnimationURL is Script, DeploySetting {
13 | address internal link3Profile = 0x57e12b7a5F38A7F9c23eBD0400e6E53F2a45F271;
14 | string internal animationUrl =
15 | "https://cyberconnect.mypinata.cloud/ipfs/bafkreic7ur7evrpy45md2xpth3zvy4mjcczzodjg7xciupty6dvmliye6i";
16 |
17 | function run() external {
18 | _setDeployParams();
19 | // make sure only on anvil
20 | require(block.chainid == 5, "ONLY_GOERLI");
21 | vm.startBroadcast();
22 |
23 | LibDeploy.deployLink3Descriptor(
24 | vm,
25 | deployParams.deployerContract,
26 | true,
27 | animationUrl,
28 | link3Profile,
29 | deployParams.link3Owner
30 | );
31 |
32 | vm.stopBroadcast();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/script/animation_url/goerli-5/SetAnimationURL.s.sol.template:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { ProfileNFT } from "../../../src/core/ProfileNFT.sol";
7 | import { Link3ProfileDescriptor } from "../../../src/periphery/Link3ProfileDescriptor.sol";
8 | import { Create2Deployer } from "../../../src/deployer/Create2Deployer.sol";
9 | import { LibDeploy } from "../../libraries/LibDeploy.sol";
10 | import { DeploySetting } from "../../libraries/DeploySetting.sol";
11 |
12 | contract SetAnimationURL is Script, DeploySetting {
13 | address internal link3Profile = LINK3_PROFILE;
14 | string internal animationUrl = "ANIMATION_URL";
15 |
16 | function run() external {
17 | _setDeployParams();
18 | // make sure only on anvil
19 | require(block.chainid == 5, "ONLY_GOERLI");
20 | vm.startBroadcast();
21 |
22 | LibDeploy.deployLink3Descriptor(
23 | vm,
24 | deployParams.deployerContract,
25 | true,
26 | animationUrl,
27 | link3Profile,
28 | deployParams.link3Owner
29 | );
30 |
31 | vm.stopBroadcast();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/script/animation_url/mainnet-1/SetAnimationURL.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { ProfileNFT } from "../../../src/core/ProfileNFT.sol";
7 | import { Link3ProfileDescriptor } from "../../../src/periphery/Link3ProfileDescriptor.sol";
8 | import { Create2Deployer } from "../../../src/deployer/Create2Deployer.sol";
9 | import { LibDeploy } from "../../libraries/LibDeploy.sol";
10 | import { DeploySetting } from "../../libraries/DeploySetting.sol";
11 |
12 | contract SetAnimationURL is Script, DeploySetting {
13 | address internal link3Profile = 0x8CC6517e45dB7a0803feF220D9b577326A12033f;
14 | string internal animationUrl =
15 | "https://cyberconnect.mypinata.cloud/ipfs/bafkreigjfjobgbh6voodb4z4u3nfpuchwb5usolon6i67kecelki2uzb6y";
16 |
17 | function run() external {
18 | _setDeployParams();
19 | // make sure only on anvil
20 | require(block.chainid == 1, "ONLY_MAINNET");
21 | vm.startBroadcast();
22 |
23 | LibDeploy.deployLink3Descriptor(
24 | vm,
25 | deployParams.deployerContract,
26 | true,
27 | animationUrl,
28 | link3Profile,
29 | deployParams.link3Owner
30 | );
31 |
32 | vm.stopBroadcast();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/script/animation_url/mainnet-1/SetAnimationURL.s.sol.template:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { ProfileNFT } from "../../../src/core/ProfileNFT.sol";
7 | import { Link3ProfileDescriptor } from "../../../src/periphery/Link3ProfileDescriptor.sol";
8 | import { Create2Deployer } from "../../../src/deployer/Create2Deployer.sol";
9 | import { LibDeploy } from "../../libraries/LibDeploy.sol";
10 | import { DeploySetting } from "../../libraries/DeploySetting.sol";
11 |
12 | contract SetAnimationURL is Script, DeploySetting {
13 | address internal link3Profile = LINK3_PROFILE;
14 | string internal animationUrl = "ANIMATION_URL";
15 |
16 | function run() external {
17 | _setDeployParams();
18 | // make sure only on anvil
19 | require(block.chainid == 1, "ONLY_MAINNET");
20 | vm.startBroadcast();
21 |
22 | LibDeploy.deployLink3Descriptor(
23 | vm,
24 | deployParams.deployerContract,
25 | true,
26 | animationUrl,
27 | link3Profile,
28 | deployParams.link3Owner
29 | );
30 |
31 | vm.stopBroadcast();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/script/animation_url/nova-42170/SetAnimationURL.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { ProfileNFT } from "../../../src/core/ProfileNFT.sol";
7 | import { Link3ProfileDescriptor } from "../../../src/periphery/Link3ProfileDescriptor.sol";
8 | import { Create2Deployer } from "../../../src/deployer/Create2Deployer.sol";
9 | import { LibDeploy } from "../../libraries/LibDeploy.sol";
10 | import { DeploySetting } from "../../libraries/DeploySetting.sol";
11 |
12 | contract SetAnimationURL is Script, DeploySetting {
13 | address internal link3Profile = 0x2723522702093601e6360CAe665518C4f63e9dA6;
14 | string internal animationUrl =
15 | "https://cyberconnect.mypinata.cloud/ipfs/bafkreiaiurmd4gpnu4nqjlddbt2r57ipshpsz77bf7mybun36psiggrbui";
16 |
17 | function run() external {
18 | _setDeployParams();
19 | // make sure only on anvil
20 | require(block.chainid == 42170, "ONLY_NOVA");
21 | vm.startBroadcast();
22 |
23 | LibDeploy.deployLink3Descriptor(
24 | vm,
25 | deployParams.deployerContract,
26 | true,
27 | animationUrl,
28 | link3Profile,
29 | deployParams.link3Owner
30 | );
31 |
32 | vm.stopBroadcast();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/script/animation_url/nova-42170/SetAnimationURL.s.sol.template:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { ProfileNFT } from "../../../src/core/ProfileNFT.sol";
7 | import { Link3ProfileDescriptor } from "../../../src/periphery/Link3ProfileDescriptor.sol";
8 | import { Create2Deployer } from "../../../src/deployer/Create2Deployer.sol";
9 | import { LibDeploy } from "../../libraries/LibDeploy.sol";
10 | import { DeploySetting } from "../../libraries/DeploySetting.sol";
11 |
12 | contract SetAnimationURL is Script, DeploySetting {
13 | address internal link3Profile = LINK3_PROFILE;
14 | string internal animationUrl = "ANIMATION_URL";
15 |
16 | function run() external {
17 | _setDeployParams();
18 | // make sure only on anvil
19 | require(block.chainid == 42170, "ONLY_NOVA");
20 | vm.startBroadcast();
21 |
22 | LibDeploy.deployLink3Descriptor(
23 | vm,
24 | deployParams.deployerContract,
25 | true,
26 | animationUrl,
27 | link3Profile,
28 | deployParams.link3Owner
29 | );
30 |
31 | vm.stopBroadcast();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/script/animation_url/polygon-137/SetAnimationURL.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { ProfileNFT } from "../../../src/core/ProfileNFT.sol";
7 | import { Link3ProfileDescriptor } from "../../../src/periphery/Link3ProfileDescriptor.sol";
8 | import { Create2Deployer } from "../../../src/deployer/Create2Deployer.sol";
9 | import { LibDeploy } from "../../libraries/LibDeploy.sol";
10 | import { DeploySetting } from "../../libraries/DeploySetting.sol";
11 |
12 | contract SetAnimationURL is Script, DeploySetting {
13 | address internal link3Profile = 0xbF029d040e3E6DA7b768b759dD9D67D84c73C06f;
14 | string internal animationUrl =
15 | "https://cyberconnect.mypinata.cloud/ipfs/bafkreiebcj2it5hirwrfbfhjlwr7pxbjqvojtxht4bcjhvvnjxqwomqqly";
16 |
17 | function run() external {
18 | _setDeployParams();
19 | // make sure only on anvil
20 | require(block.chainid == 137, "ONLY_POLYGON");
21 | vm.startBroadcast();
22 |
23 | LibDeploy.deployLink3Descriptor(
24 | vm,
25 | deployParams.deployerContract,
26 | true,
27 | animationUrl,
28 | link3Profile,
29 | deployParams.link3Owner
30 | );
31 |
32 | vm.stopBroadcast();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/script/animation_url/polygon-137/SetAnimationURL.s.sol.template:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { ProfileNFT } from "../../../src/core/ProfileNFT.sol";
7 | import { Link3ProfileDescriptor } from "../../../src/periphery/Link3ProfileDescriptor.sol";
8 | import { Create2Deployer } from "../../../src/deployer/Create2Deployer.sol";
9 | import { LibDeploy } from "../../libraries/LibDeploy.sol";
10 | import { DeploySetting } from "../../libraries/DeploySetting.sol";
11 |
12 | contract SetAnimationURL is Script, DeploySetting {
13 | address internal link3Profile = LINK3_PROFILE;
14 | string internal animationUrl = "ANIMATION_URL";
15 |
16 | function run() external {
17 | _setDeployParams();
18 | // make sure only on anvil
19 | require(block.chainid == 137, "ONLY_POLYGON");
20 | vm.startBroadcast();
21 |
22 | LibDeploy.deployLink3Descriptor(
23 | vm,
24 | deployParams.deployerContract,
25 | true,
26 | animationUrl,
27 | link3Profile,
28 | deployParams.link3Owner
29 | );
30 |
31 | vm.stopBroadcast();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/script/animation_url/rinkeby-4/SetAnimationURL.s.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { ProfileNFT } from "../../../src/core/ProfileNFT.sol";
7 | import { Link3ProfileDescriptor } from "../../../src/periphery/Link3ProfileDescriptor.sol";
8 | import { Create2Deployer } from "../../../src/deployer/Create2Deployer.sol";
9 | import { LibDeploy } from "../../libraries/LibDeploy.sol";
10 | import { DeploySetting } from "../../libraries/DeploySetting.sol";
11 |
12 | contract SetAnimationURL is Script, DeploySetting {
13 | address internal link3Profile = 0xb9FDA6C1C56dC7AC3aE787a46fD3434DA991626D;
14 | string internal animationUrl =
15 | "https://cyberconnect.mypinata.cloud/ipfs/bafkreifq5vu6gl4q4c5fb23m5w3wyijumonpfb7dki7eodx2222ogfb3lu";
16 |
17 | function run() external {
18 | _setDeployParams();
19 | // make sure only on anvil
20 | require(block.chainid == 4, "ONLY_RINKEBY");
21 | vm.startBroadcast();
22 |
23 | LibDeploy.deployLink3Descriptor(
24 | vm,
25 | deployParams.deployerContract,
26 | true,
27 | animationUrl,
28 | link3Profile,
29 | deployParams.link3Owner
30 | );
31 |
32 | vm.stopBroadcast();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/script/animation_url/rinkeby-4/SetAnimationURL.s.sol.template:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Script.sol";
6 | import { ProfileNFT } from "../../../src/core/ProfileNFT.sol";
7 | import { Link3ProfileDescriptor } from "../../../src/periphery/Link3ProfileDescriptor.sol";
8 | import { Create2Deployer } from "../../../src/deployer/Create2Deployer.sol";
9 | import { LibDeploy } from "../../libraries/LibDeploy.sol";
10 | import { DeploySetting } from "../../libraries/DeploySetting.sol";
11 |
12 | contract SetAnimationURL is Script, DeploySetting {
13 | address internal link3Profile = LINK3_PROFILE;
14 | string internal animationUrl = "ANIMATION_URL";
15 |
16 | function run() external {
17 | _setDeployParams();
18 | // make sure only on anvil
19 | require(block.chainid == 4, "ONLY_RINKEBY");
20 | vm.startBroadcast();
21 |
22 | LibDeploy.deployLink3Descriptor(
23 | vm,
24 | deployParams.deployerContract,
25 | true,
26 | animationUrl,
27 | link3Profile,
28 | deployParams.link3Owner
29 | );
30 |
31 | vm.stopBroadcast();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/script/libraries/DeployNamespace.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 | import "forge-std/console.sol";
5 | import "forge-std/Vm.sol";
6 | import "./LibDeploy.sol";
7 |
8 | library DeployNamespace {
9 | struct DeployNamespaceParams {
10 | address engineProxy;
11 | address namespaceOwner;
12 | string name;
13 | string symbol;
14 | address profileFac;
15 | address subFac;
16 | address essFac;
17 | }
18 |
19 | function deployNamespace(Vm vm, DeployNamespaceParams memory params)
20 | internal
21 | returns (address)
22 | {
23 | bytes32 salt = keccak256(bytes(params.name));
24 | (address profile, , ) = LibDeploy.createNamespace(
25 | params.engineProxy,
26 | params.namespaceOwner,
27 | params.name,
28 | params.symbol,
29 | salt,
30 | params.profileFac,
31 | params.subFac,
32 | params.essFac
33 | );
34 | LibDeploy._write(
35 | vm,
36 | string(abi.encodePacked(params.name, " profile")),
37 | profile
38 | );
39 | return profile;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/slither.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "filter_paths": "lib|test|src/dependencies",
3 | "solc_remaps": [
4 | "ds-test/=lib/ds-test/src/",
5 | "forge-std/=lib/forge-std/src/",
6 | "openzeppelin-contracts/=lib/openzeppelin-contracts/",
7 | "solmate/=lib/solmate/src/"
8 | ]
9 | }
--------------------------------------------------------------------------------
/src/base/EIP712.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { DataTypes } from "../libraries/DataTypes.sol";
6 |
7 | abstract contract EIP712 {
8 | /*//////////////////////////////////////////////////////////////
9 | STATES
10 | //////////////////////////////////////////////////////////////*/
11 | bytes32 internal constant _HASHED_VERSION = keccak256("1");
12 | bytes32 private constant _TYPE_HASH =
13 | keccak256(
14 | "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
15 | );
16 |
17 | /*//////////////////////////////////////////////////////////////
18 | PUBLIC VIEW
19 | //////////////////////////////////////////////////////////////*/
20 |
21 | /**
22 | * @notice Returns the contract's {EIP712} domain separator.
23 | *
24 | * @return bytes32 the contract's {EIP712} domain separator.
25 | */
26 | // solhint-disable-next-line func-name-mixedcase
27 | function DOMAIN_SEPARATOR() public view returns (bytes32) {
28 | return
29 | keccak256(
30 | abi.encode(
31 | _TYPE_HASH,
32 | keccak256(bytes(_domainSeparatorName())),
33 | _HASHED_VERSION,
34 | block.chainid,
35 | address(this)
36 | )
37 | );
38 | }
39 |
40 | /*//////////////////////////////////////////////////////////////
41 | INTERNAL
42 | //////////////////////////////////////////////////////////////*/
43 |
44 | function _requiresExpectedSigner(
45 | bytes32 digest,
46 | address expectedSigner,
47 | uint8 v,
48 | bytes32 r,
49 | bytes32 s,
50 | uint256 deadline
51 | ) internal view {
52 | require(deadline >= block.timestamp, "DEADLINE_EXCEEDED");
53 | require(
54 | uint256(s) <=
55 | 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,
56 | "INVALID_SIGNATURE_S_VAULE"
57 | );
58 |
59 | address recoveredAddress = ecrecover(digest, v, r, s);
60 | require(recoveredAddress == expectedSigner, "INVALID_SIGNATURE");
61 | }
62 |
63 | function _requiresExpectedSigner(
64 | bytes32 digest,
65 | address expectedSigner,
66 | DataTypes.EIP712Signature calldata sig
67 | ) internal view {
68 | _requiresExpectedSigner(
69 | digest,
70 | expectedSigner,
71 | sig.v,
72 | sig.r,
73 | sig.s,
74 | sig.deadline
75 | );
76 | }
77 |
78 | function _hashTypedDataV4(bytes32 structHash)
79 | internal
80 | view
81 | virtual
82 | returns (bytes32)
83 | {
84 | return
85 | keccak256(
86 | abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR(), structHash)
87 | );
88 | }
89 |
90 | function _domainSeparatorName()
91 | internal
92 | view
93 | virtual
94 | returns (string memory);
95 | }
96 |
--------------------------------------------------------------------------------
/src/dependencies/openzeppelin/Pausable.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 | // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)
3 |
4 | pragma solidity ^0.8.0;
5 |
6 | /**
7 | * @dev modified from OpenZeppelin Pausable.sol, removing Context
8 | *
9 | * @dev Contract module which allows children to implement an emergency stop
10 | * mechanism that can be triggered by an authorized account.
11 | *
12 | * This module is used through inheritance. It will make available the
13 | * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
14 | * the functions of your contract. Note that they will not be pausable by
15 | * simply including this module, only once the modifiers are put in place.
16 | */
17 | abstract contract Pausable {
18 | /**
19 | * @dev Emitted when the pause is triggered by `account`.
20 | */
21 | event Paused(address account);
22 |
23 | /**
24 | * @dev Emitted when the pause is lifted by `account`.
25 | */
26 | event Unpaused(address account);
27 |
28 | bool private _paused;
29 |
30 | /**
31 | * @dev Modifier to make a function callable only when the contract is not paused.
32 | *
33 | * Requirements:
34 | *
35 | * - The contract must not be paused.
36 | */
37 | modifier whenNotPaused() {
38 | _requireNotPaused();
39 | _;
40 | }
41 |
42 | /**
43 | * @dev Modifier to make a function callable only when the contract is paused.
44 | *
45 | * Requirements:
46 | *
47 | * - The contract must be paused.
48 | */
49 | modifier whenPaused() {
50 | _requirePaused();
51 | _;
52 | }
53 |
54 | /**
55 | * @dev Returns true if the contract is paused, and false otherwise.
56 | */
57 | function paused() public view virtual returns (bool) {
58 | return _paused;
59 | }
60 |
61 | /**
62 | * @dev Throws if the contract is paused.
63 | */
64 | function _requireNotPaused() internal view virtual {
65 | require(!paused(), "Pausable: paused");
66 | }
67 |
68 | /**
69 | * @dev Throws if the contract is not paused.
70 | */
71 | function _requirePaused() internal view virtual {
72 | require(paused(), "Pausable: not paused");
73 | }
74 |
75 | /**
76 | * @dev Triggers stopped state.
77 | *
78 | * Requirements:
79 | *
80 | * - The contract must not be paused.
81 | */
82 | function _pause() internal virtual whenNotPaused {
83 | _paused = true;
84 | emit Paused(msg.sender);
85 | }
86 |
87 | /**
88 | * @dev Returns to normal state.
89 | *
90 | * Requirements:
91 | *
92 | * - The contract must be paused.
93 | */
94 | function _unpause() internal virtual whenPaused {
95 | _paused = false;
96 | emit Unpaused(msg.sender);
97 | }
98 | }
--------------------------------------------------------------------------------
/src/dependencies/openzeppelin/ReentrancyGuard.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 | // OpenZeppelin Contracts v4.7.0 (security/ReentrancyGuard.sol)
3 |
4 | import { Initializable } from "openzeppelin-contracts/contracts/proxy/utils/Initializable.sol";
5 |
6 | pragma solidity ^0.8.0;
7 |
8 | /**
9 | * @dev modified from OpenZeppelin ReentrancyGuard.sol adding initialize func
10 | *
11 | * @dev Contract module that helps prevent reentrant calls to a function.
12 | *
13 | * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
14 | * available, which can be applied to functions to make sure there are no nested
15 | * (reentrant) calls to them.
16 | *
17 | * Note that because there is a single `nonReentrant` guard, functions marked as
18 | * `nonReentrant` may not call one another. This can be worked around by making
19 | * those functions `private`, and then adding `external` `nonReentrant` entry
20 | * points to them.
21 | *
22 | * TIP: If you would like to learn more about reentrancy and alternative ways
23 | * to protect against it, check out our blog post
24 | * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
25 | */
26 | abstract contract ReentrancyGuard is Initializable {
27 | // Booleans are more expensive than uint256 or any type that takes up a full
28 | // word because each write operation emits an extra SLOAD to first read the
29 | // slot's contents, replace the bits taken up by the boolean, and then write
30 | // back. This is the compiler's defense against contract upgrades and
31 | // pointer aliasing, and it cannot be disabled.
32 |
33 | // The values being non-zero value makes deployment a bit more expensive,
34 | // but in exchange the refund on every call to nonReentrant will be lower in
35 | // amount. Since refunds are capped to a percentage of the total
36 | // transaction's gas, it is best to keep them low in cases like this one, to
37 | // increase the likelihood of the full refund coming into effect.
38 | uint256 private constant _NOT_ENTERED = 1;
39 | uint256 private constant _ENTERED = 2;
40 |
41 | uint256 private _status;
42 |
43 |
44 | function __ReentrancyGuard_init() internal onlyInitializing {
45 | _status = _NOT_ENTERED;
46 | }
47 |
48 | /**
49 | * @dev Prevents a contract from calling itself, directly or indirectly.
50 | * Calling a `nonReentrant` function from another `nonReentrant`
51 | * function is not supported. It is possible to prevent this from happening
52 | * by making the `nonReentrant` function external, and making it call a
53 | * `private` function that does the actual work.
54 | */
55 | modifier nonReentrant() {
56 | // On the first call to nonReentrant, _notEntered will be true
57 | require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
58 |
59 | // Any calls to nonReentrant after this point will fail
60 | _status = _ENTERED;
61 |
62 | _;
63 |
64 | // By storing the original value once again, a refund is triggered (see
65 | // https://eips.ethereum.org/EIPS/eip-2200)
66 | _status = _NOT_ENTERED;
67 | }
68 | }
--------------------------------------------------------------------------------
/src/dependencies/solmate/Auth.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity >=0.8.0;
4 |
5 | import { Initializable } from "openzeppelin-contracts/contracts/proxy/utils/Initializable.sol";
6 |
7 | /// @notice Adapted from Solmate's Auth.sol with initializer replacing the constructor.
8 |
9 | /// @notice Provides a flexible and updatable auth pattern which is completely separate from application logic.
10 | /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Auth.sol)
11 | /// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol)
12 | abstract contract Auth is Initializable {
13 | event OwnerUpdated(address indexed user, address indexed newOwner);
14 |
15 | event AuthorityUpdated(address indexed user, Authority indexed newAuthority);
16 |
17 | address public owner;
18 |
19 | Authority public authority;
20 |
21 | function __Auth_Init(address _owner, Authority _authority) internal onlyInitializing {
22 | owner = _owner;
23 | authority = _authority;
24 |
25 | emit OwnerUpdated(msg.sender, _owner);
26 | emit AuthorityUpdated(msg.sender, _authority);
27 | }
28 |
29 | modifier requiresAuth() virtual {
30 | require(isAuthorized(msg.sender, msg.sig), "UNAUTHORIZED");
31 |
32 | _;
33 | }
34 |
35 | function isAuthorized(address user, bytes4 functionSig) internal view virtual returns (bool) {
36 | Authority auth = authority; // Memoizing authority saves us a warm SLOAD, around 100 gas.
37 |
38 | // Checking if the caller is the owner only after calling the authority saves gas in most cases, but be
39 | // aware that this makes protected functions uncallable even to the owner if the authority is out of order.
40 | return (address(auth) != address(0) && auth.canCall(user, address(this), functionSig)) || user == owner;
41 | }
42 |
43 | function setAuthority(Authority newAuthority) public virtual {
44 | // We check if the caller is the owner first because we want to ensure they can
45 | // always swap out the authority even if it's reverting or using up a lot of gas.
46 | require(msg.sender == owner || authority.canCall(msg.sender, address(this), msg.sig), "UNAUTHORIZED");
47 |
48 | authority = newAuthority;
49 |
50 | emit AuthorityUpdated(msg.sender, newAuthority);
51 | }
52 |
53 | function setOwner(address newOwner) public virtual requiresAuth {
54 | owner = newOwner;
55 |
56 | emit OwnerUpdated(msg.sender, newOwner);
57 | }
58 | }
59 |
60 | /// @notice A generic interface for a contract which provides authorization data to an Auth instance.
61 | /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Auth.sol)
62 | /// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol)
63 | interface Authority {
64 | function canCall(
65 | address user,
66 | address target,
67 | bytes4 functionSig
68 | ) external view returns (bool);
69 | }
--------------------------------------------------------------------------------
/src/dependencies/solmate/Owned.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | import { Initializable } from "openzeppelin-contracts/contracts/proxy/utils/Initializable.sol";
4 |
5 | pragma solidity >=0.8.0;
6 |
7 | /// @notice Adapted from Solmate's Owned.sol with initializer replacing the constructor.
8 |
9 | /// @notice Simple single owner authorization mixin.
10 | /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)
11 | abstract contract Owned is Initializable {
12 | /*//////////////////////////////////////////////////////////////
13 | EVENTS
14 | //////////////////////////////////////////////////////////////*/
15 |
16 | event OwnerUpdated(address indexed user, address indexed newOwner);
17 |
18 | /*//////////////////////////////////////////////////////////////
19 | OWNERSHIP STORAGE
20 | //////////////////////////////////////////////////////////////*/
21 |
22 | address public owner;
23 |
24 | modifier onlyOwner() virtual {
25 | require(msg.sender == owner, "UNAUTHORIZED");
26 |
27 | _;
28 | }
29 |
30 | /*//////////////////////////////////////////////////////////////
31 | CONSTRUCTOR
32 | //////////////////////////////////////////////////////////////*/
33 |
34 | function __Owned_Init(address _owner) internal onlyInitializing {
35 | require(_owner != address(0), "ZERO_ADDRESS");
36 | owner = _owner;
37 |
38 | emit OwnerUpdated(address(0), _owner);
39 | }
40 |
41 | /*//////////////////////////////////////////////////////////////
42 | OWNERSHIP LOGIC
43 | //////////////////////////////////////////////////////////////*/
44 |
45 | function setOwner(address newOwner) public virtual onlyOwner {
46 | require(newOwner != address(0), "ZERO_ADDRESS");
47 | owner = newOwner;
48 |
49 | emit OwnerUpdated(msg.sender, newOwner);
50 | }
51 | }
--------------------------------------------------------------------------------
/src/deployer/Create2Deployer.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 | pragma solidity 0.8.14;
3 |
4 | contract Create2Deployer {
5 | event Deployed(address addr, bytes32 salt);
6 |
7 | function deploy(bytes memory code, bytes32 salt) public returns (address) {
8 | address addr;
9 | require(code.length != 0, "Create2: bytecode length is zero");
10 | assembly {
11 | addr := create2(0, add(code, 0x20), mload(code), salt)
12 | if iszero(extcodesize(addr)) {
13 | revert(0, 0)
14 | }
15 | }
16 |
17 | emit Deployed(addr, salt);
18 | return addr;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/deployer/EssenceDeployer.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { IEssenceDeployer } from "../interfaces/IEssenceDeployer.sol";
6 |
7 | import { DataTypes } from "../libraries/DataTypes.sol";
8 |
9 | import { EssenceNFT } from "../core/EssenceNFT.sol";
10 |
11 | contract EssenceDeployer is IEssenceDeployer {
12 | DataTypes.EssenceDeployParameters public override essParams;
13 |
14 | /// @inheritdoc IEssenceDeployer
15 | function deployEssence(bytes32 salt, address profileProxy)
16 | external
17 | override
18 | returns (address addr)
19 | {
20 | essParams.profileProxy = profileProxy;
21 | addr = address(new EssenceNFT{ salt: salt }());
22 | delete essParams;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/deployer/ProfileDeployer.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { IProfileDeployer } from "../interfaces/IProfileDeployer.sol";
6 |
7 | import { DataTypes } from "../libraries/DataTypes.sol";
8 |
9 | import { ProfileNFT } from "../core/ProfileNFT.sol";
10 |
11 | contract ProfileDeployer is IProfileDeployer {
12 | DataTypes.ProfileDeployParameters public override profileParams;
13 |
14 | /// @inheritdoc IProfileDeployer
15 | function deployProfile(
16 | bytes32 salt,
17 | address engine,
18 | address subscribeBeacon,
19 | address essenceBeacon
20 | ) external override returns (address addr) {
21 | profileParams.engine = engine;
22 | profileParams.essenceBeacon = essenceBeacon;
23 | profileParams.subBeacon = subscribeBeacon;
24 | addr = address(new ProfileNFT{ salt: salt }());
25 | delete profileParams;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/deployer/SubscribeDeployer.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { ISubscribeDeployer } from "../interfaces/ISubscribeDeployer.sol";
6 |
7 | import { DataTypes } from "../libraries/DataTypes.sol";
8 |
9 | import { SubscribeNFT } from "../core/SubscribeNFT.sol";
10 |
11 | contract SubscribeDeployer is ISubscribeDeployer {
12 | DataTypes.SubscribeDeployParameters public override subParams;
13 |
14 | /// @inheritdoc ISubscribeDeployer
15 | function deploySubscribe(bytes32 salt, address profileProxy)
16 | external
17 | override
18 | returns (address addr)
19 | {
20 | subParams.profileProxy = profileProxy;
21 | addr = address(new SubscribeNFT{ salt: salt }());
22 | delete subParams;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/interfaces/ICyberBox.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { ICyberBoxEvents } from "../interfaces/ICyberBoxEvents.sol";
6 |
7 | interface ICyberBox is ICyberBoxEvents {
8 | /**
9 | * @notice Gets the signer for the CyberBox NFT.
10 | *
11 | * @return address The signer of CyberBox NFT.
12 | */
13 | function getSigner() external view returns (address);
14 | }
15 |
--------------------------------------------------------------------------------
/src/interfaces/ICyberBoxEvents.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | interface ICyberBoxEvents {
6 | /**
7 | * @notice Emiited when the CyberBox is initialized.
8 | *
9 | * @param owner The address of the CyberBox owner.
10 | * @param signer The address of the CyberBox signer.
11 | * @param name The name for the CyberBox.
12 | * @param symbol The symbol for the CyberBox.
13 | */
14 | event Initialize(
15 | address indexed owner,
16 | address indexed signer,
17 | string name,
18 | string symbol
19 | );
20 |
21 | /**
22 | * @notice Emitted when a new signer has been set.
23 | *
24 | * @param preSigner The previous signer address.
25 | * @param newSigner The newly set signer address.
26 | */
27 | event SetSigner(address indexed preSigner, address indexed newSigner);
28 |
29 | /**
30 | * @notice Emitted when a profile claims a box nft.
31 | *
32 | * @param to The claimer address.
33 | * @param boxId The box id that has been claimed.
34 | */
35 | event ClaimBox(address indexed to, uint256 indexed boxId);
36 | }
37 |
--------------------------------------------------------------------------------
/src/interfaces/ICyberEngineEvents.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { DataTypes } from "../libraries/DataTypes.sol";
6 |
7 | interface ICyberEngineEvents {
8 | /**
9 | * @notice Emiited when the engine is initialized
10 | *
11 | * @param owner The address of the engine owner.
12 | * @param rolesAuthority The address of the role authority.
13 | */
14 | event Initialize(address indexed owner, address indexed rolesAuthority);
15 |
16 | /**
17 | * @notice Emitted when a profile middleware has been allowed.
18 | *
19 | * @param mw The middleware address.
20 | * @param preAllowed The previously allow state.
21 | * @param newAllowed The newly set allow state.
22 | */
23 | event AllowProfileMw(
24 | address indexed mw,
25 | bool indexed preAllowed,
26 | bool indexed newAllowed
27 | );
28 |
29 | /**
30 | * @notice Emitted when a profile middleware has been set.
31 | *
32 | * @param namespace The namespace address.
33 | * @param mw The middleware address.
34 | * @param returnData The profile middeware data.
35 | */
36 | event SetProfileMw(address indexed namespace, address mw, bytes returnData);
37 |
38 | /**
39 | * @notice Emitted when a subscription middleware has been allowed.
40 | *
41 | * @param mw The middleware address.
42 | * @param preAllowed The previously allow state.
43 | * @param newAllowed The newly set allow state.
44 | */
45 | event AllowSubscribeMw(
46 | address indexed mw,
47 | bool indexed preAllowed,
48 | bool indexed newAllowed
49 | );
50 |
51 | /**
52 | * @notice Emitted when a essence middleware has been allowed.
53 | *
54 | * @param mw The middleware address.
55 | * @param preAllowed The previously allow state.
56 | * @param newAllowed The newly set allow state.
57 | */
58 | event AllowEssenceMw(
59 | address indexed mw,
60 | bool indexed preAllowed,
61 | bool indexed newAllowed
62 | );
63 |
64 | /**
65 | * @notice Emitted when a namespace has been created
66 | *
67 | * @param namespace The namespace address.
68 | * @param name The namespace name.
69 | * @param symbol The namespace symbol.
70 | */
71 | event CreateNamespace(
72 | address indexed namespace,
73 | string name,
74 | string symbol
75 | );
76 | }
77 |
--------------------------------------------------------------------------------
/src/interfaces/ICyberGrand.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { ICyberGrandEvents } from "../interfaces/ICyberGrandEvents.sol";
6 |
7 | interface ICyberGrand is ICyberGrandEvents {
8 | /**
9 | * @notice Gets the signer for the CyberGrand NFT.
10 | *
11 | * @return address The signer of CyberGrand NFT.
12 | */
13 | function getSigner() external view returns (address);
14 | }
15 |
--------------------------------------------------------------------------------
/src/interfaces/ICyberGrandEvents.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | interface ICyberGrandEvents {
6 | /**
7 | * @notice Emiited when the CyberGrand is initialized.
8 | *
9 | * @param owner The address of the CyberGrand owner.
10 | * @param signer The address of the CyberGrand signer.
11 | * @param name The name for the CyberGrand.
12 | * @param symbol The symbol for the CyberGrand.
13 | * @param uri The uri for the CyberGrand.
14 | */
15 | event Initialize(
16 | address indexed owner,
17 | address indexed signer,
18 | string name,
19 | string symbol,
20 | string uri
21 | );
22 |
23 | /**
24 | * @notice Emitted when a new signer has been set.
25 | *
26 | * @param preSigner The previous signer address.
27 | * @param newSigner The newly set signer address.
28 | */
29 | event SetSigner(address indexed preSigner, address indexed newSigner);
30 |
31 | /**
32 | * @notice Emitted when a grand nft has been claimed.
33 | *
34 | * @param to The claimer address.
35 | * @param tokenId The token id that has been claimed.
36 | */
37 | event ClaimGrand(address indexed to, uint256 indexed tokenId);
38 | }
39 |
--------------------------------------------------------------------------------
/src/interfaces/ICyberNFTBase.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { DataTypes } from "../libraries/DataTypes.sol";
6 |
7 | interface ICyberNFTBase {
8 | /**
9 | * @notice Gets total number of tokens in existence, burned tokens will reduce the count.
10 | *
11 | * @return uint256 The total supply.
12 | */
13 | function totalSupply() external view returns (uint256);
14 |
15 | /**
16 | * @notice Gets the total number of minted tokens.
17 | *
18 | * @return uint256 The total minted tokens.
19 | */
20 | function totalMinted() external view returns (uint256);
21 |
22 | /**
23 | * @notice Gets the total number of burned tokens.
24 | *
25 | * @return uint256 The total burned tokens.
26 | */
27 | function totalBurned() external view returns (uint256);
28 |
29 | /**
30 | * @notice The EIP-712 permit function.
31 | *
32 | * @param spender The spender address.
33 | * @param tokenId The token ID to approve.
34 | * @param sig Must produce valid EIP712 signature with `s`, `r`, `v` and `deadline`.
35 | */
36 | function permit(
37 | address spender,
38 | uint256 tokenId,
39 | DataTypes.EIP712Signature calldata sig
40 | ) external;
41 |
42 | /**
43 | * @notice Burns a token.
44 | *
45 | * @param tokenId The token ID to burn.
46 | */
47 | function burn(uint256 tokenId) external;
48 | }
49 |
--------------------------------------------------------------------------------
/src/interfaces/IEssenceDeployer.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | interface IEssenceDeployer {
6 | /**
7 | * @notice Parameters when constructing a EssenceNFT.
8 | *
9 | * @return profileProxy The ProfileNFT proxy address.
10 | */
11 | function essParams() external view returns (address profileProxy);
12 |
13 | /**
14 | * @notice Deploy a new EssenceNFT.
15 | *
16 | * @param salt The salt used to generate contract address in a deterministic way.
17 | * @param profileProxy The CyberEngine address.
18 | *
19 | * @return addr The newly deployed EssenceNFT address.
20 | */
21 | function deployEssence(bytes32 salt, address profileProxy)
22 | external
23 | returns (address addr);
24 | }
25 |
--------------------------------------------------------------------------------
/src/interfaces/IEssenceMiddleware.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | interface IEssenceMiddleware {
6 | /**
7 | * @notice Sets essence related data for middleware.
8 | *
9 | * @param profileId The profile id that owns this middleware.
10 | * @param essenceId The essence id that owns this middleware.
11 | * @param data Extra data to set.
12 | */
13 | function setEssenceMwData(
14 | uint256 profileId,
15 | uint256 essenceId,
16 | bytes calldata data
17 | ) external returns (bytes memory);
18 |
19 | /**
20 | * @notice Process that runs before the essenceNFT mint happens.
21 | *
22 | * @param profileId The profile Id.
23 | * @param essenceId The essence Id.
24 | * @param collector The collector address.
25 | * @param essenceNFT The essence nft address.
26 | * @param data Extra data to process.
27 | */
28 | function preProcess(
29 | uint256 profileId,
30 | uint256 essenceId,
31 | address collector,
32 | address essenceNFT,
33 | bytes calldata data
34 | ) external;
35 |
36 | /**
37 | * @notice Process that runs after the essenceNFT mint happens.
38 | *
39 | * @param profileId The profile Id.
40 | * @param essenceId The essence Id.
41 | * @param collector The collector address.
42 | * @param essenceNFT The essence nft address.
43 | * @param data Extra data to process.
44 | */
45 | function postProcess(
46 | uint256 profileId,
47 | uint256 essenceId,
48 | address collector,
49 | address essenceNFT,
50 | bytes calldata data
51 | ) external;
52 | }
53 |
--------------------------------------------------------------------------------
/src/interfaces/IEssenceNFT.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { IEssenceNFTEvents } from "./IEssenceNFTEvents.sol";
6 |
7 | interface IEssenceNFT is IEssenceNFTEvents {
8 | /**
9 | * @notice Mints the Essence NFT.
10 | *
11 | * @param to The recipient address.
12 | * @return uint256 The token id.
13 | */
14 | function mint(address to) external returns (uint256);
15 |
16 | /**
17 | * @notice Initializes the Essence NFT.
18 | *
19 | * @param profileId The profile ID for the Essence NFT.
20 | * @param essenceId The essence ID for the Essence NFT.
21 | * @param name The name for the Essence NFT.
22 | * @param symbol The symbol for the Essence NFT.
23 | * @param transferable Whether the Essence NFT is transferable.
24 | */
25 | function initialize(
26 | uint256 profileId,
27 | uint256 essenceId,
28 | string calldata name,
29 | string calldata symbol,
30 | bool transferable
31 | ) external;
32 |
33 | /**
34 | * @notice Check if this essence NFT is transferable.
35 | *
36 | * @return bool Whether this Essence NFT is transferable.
37 | */
38 | function isTransferable() external returns (bool);
39 | }
40 |
--------------------------------------------------------------------------------
/src/interfaces/IEssenceNFTEvents.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | interface IEssenceNFTEvents {
6 | /**
7 | * @notice Emiited when the essence NFT is initialized
8 | *
9 | * @param profileId The profile ID for the Essence NFT.
10 | * @param essenceId The essence ID for the Essence NFT.
11 | * @param name The name for the Essence NFT.
12 | * @param symbol The symbol for the Essence NFT.
13 | * @param transferable Whether the Essence NFT is transferable.
14 | */
15 | event Initialize(
16 | uint256 indexed profileId,
17 | uint256 indexed essenceId,
18 | string name,
19 | string symbol,
20 | bool transferable
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/src/interfaces/IMB.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { IMBEvents } from "../interfaces/IMBEvents.sol";
6 |
7 | interface IMB is IMBEvents {
8 | /**
9 | * @notice Gets the Box address.
10 | *
11 | * @return address The Box NFT address.
12 | */
13 | function getBoxAddr() external view returns (address);
14 | }
15 |
--------------------------------------------------------------------------------
/src/interfaces/IMBEvents.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | interface IMBEvents {
6 | /**
7 | * @notice Emiited when the MB is initialized.
8 | *
9 | * @param owner The address of the MB owner.
10 | * @param boxAddr The address of the box NFT.
11 | * @param name The name for the MB.
12 | * @param symbol The symbol for the MB.
13 | * @param uri The uri for the MB.
14 | */
15 | event Initialize(
16 | address indexed owner,
17 | address indexed boxAddr,
18 | string name,
19 | string symbol,
20 | string uri
21 | );
22 |
23 | /**
24 | * @notice Emitted when a box NFT has been opened.
25 | *
26 | * @param to The claimer address.
27 | * @param boxId The token id for MB NFT.
28 | */
29 | event OpenBox(
30 | address indexed to,
31 | uint256 indexed boxId
32 | );
33 | }
34 |
--------------------------------------------------------------------------------
/src/interfaces/IProfileDeployer.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | interface IProfileDeployer {
6 | /**
7 | * @notice Parameters when constructing a ProfileNFT.
8 | *
9 | * @return engine The CyberEngine address.
10 | * @return subBeacon The Subscribe Beacon address.
11 | * @return essenceBeacon The Essence Beacon address.
12 | */
13 | function profileParams()
14 | external
15 | view
16 | returns (
17 | address engine,
18 | address subBeacon,
19 | address essenceBeacon
20 | );
21 |
22 | /**
23 | * @notice Deploy a new ProfileNFT.
24 | *
25 | * @param salt The salt used to generate contract address in a deterministic way.
26 | * @param engine The CyberEngine address.
27 | * @param subscribeBeacon The Subscribe Beacon address.
28 | * @param essenceBeacon The Essence Beacon address.
29 | *
30 | * @return addr The newly deployed ProfileNFT address.
31 | */
32 | function deployProfile(
33 | bytes32 salt,
34 | address engine,
35 | address subscribeBeacon,
36 | address essenceBeacon
37 | ) external returns (address addr);
38 | }
39 |
--------------------------------------------------------------------------------
/src/interfaces/IProfileMiddleware.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { DataTypes } from "../libraries/DataTypes.sol";
6 |
7 | interface IProfileMiddleware {
8 | /**
9 | * @notice Sets namespace related data for middleware.
10 | *
11 | * @param namespace The related namespace address.
12 | * @param data Extra data to set.
13 | */
14 | function setProfileMwData(address namespace, bytes calldata data)
15 | external
16 | returns (bytes memory);
17 |
18 | /**
19 | * @notice Process that runs before the profileNFT creation happens.
20 | *
21 | * @param params The params for creating profile.
22 | * @param data Extra data to process.
23 | */
24 | function preProcess(
25 | DataTypes.CreateProfileParams calldata params,
26 | bytes calldata data
27 | ) external payable;
28 |
29 | /**
30 | * @notice Process that runs after the profileNFT creation happens.
31 | *
32 | * @param params The params for creating profile.
33 | * @param data Extra data to process.
34 | */
35 | function postProcess(
36 | DataTypes.CreateProfileParams calldata params,
37 | bytes calldata data
38 | ) external;
39 | }
40 |
--------------------------------------------------------------------------------
/src/interfaces/IProfileNFTDescriptor.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { DataTypes } from "../libraries/DataTypes.sol";
6 |
7 | interface IProfileNFTDescriptor {
8 | /**
9 | * @notice Sets the profile NFT animation template.
10 | *
11 | * @param template The new template.
12 | */
13 | function setAnimationTemplate(string calldata template) external;
14 |
15 | /**
16 | * @notice Generate the Profile NFT Token URI.
17 | *
18 | * @param params The dependences of token URI.
19 | * @return string The token URI.
20 | */
21 | function tokenURI(DataTypes.ConstructTokenURIParams calldata params)
22 | external
23 | view
24 | returns (string memory);
25 | }
26 |
--------------------------------------------------------------------------------
/src/interfaces/IProfileNFTDescriptorV2.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { DataTypes } from "../libraries/DataTypes.sol";
6 |
7 | interface IProfileNFTDescriptorV2 {
8 | /**
9 | * @notice Generate the Profile NFT Token URI.
10 | *
11 | * @param params The dependences of token URI.
12 | * @return string The token URI.
13 | */
14 | function tokenURI(DataTypes.ConstructTokenURIParams calldata params)
15 | external
16 | view
17 | returns (string memory);
18 | }
19 |
--------------------------------------------------------------------------------
/src/interfaces/ISubscribeDeployer.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | interface ISubscribeDeployer {
6 | /**
7 | * @notice Parameters when constructing a SubscribeNFT.
8 | *
9 | * @return profileProxy The ProfileNFT proxy address.
10 | */
11 | function subParams() external view returns (address profileProxy);
12 |
13 | /**
14 | * @notice Deploy a new SubscribeNFT.
15 | *
16 | * @param salt The salt used to generate contract address in a deterministic way.
17 | * @param profileProxy The ProfileNFT proxy address.
18 | *
19 | * @return addr The newly deployed SubscribeNFT address.
20 | */
21 | function deploySubscribe(bytes32 salt, address profileProxy)
22 | external
23 | returns (address addr);
24 | }
25 |
--------------------------------------------------------------------------------
/src/interfaces/ISubscribeMiddleware.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | interface ISubscribeMiddleware {
6 | /**
7 | * @notice Sets subscribe related data for middleware.
8 | *
9 | * @param profileId The profile id that owns this middleware.
10 | * @param data Extra data to set.
11 | */
12 | function setSubscribeMwData(uint256 profileId, bytes calldata data)
13 | external
14 | returns (bytes memory);
15 |
16 | /**
17 | * @notice Process that runs before the subscribeNFT mint happens.
18 | *
19 | * @param profileId The profile Id.
20 | * @param subscriber The subscriber address.
21 | * @param subscribeNFT The subscribe nft address.
22 | * @param data Extra data to process.
23 | */
24 | function preProcess(
25 | uint256 profileId,
26 | address subscriber,
27 | address subscribeNFT,
28 | bytes calldata data
29 | ) external;
30 |
31 | /**
32 | * @notice Process that runs after the subscribeNFT mint happens.
33 | *
34 | * @param profileId The profile Id.
35 | * @param subscriber The subscriber address.
36 | * @param subscribeNFT The subscribe nft address.
37 | * @param data Extra data to process.
38 | */
39 | function postProcess(
40 | uint256 profileId,
41 | address subscriber,
42 | address subscribeNFT,
43 | bytes calldata data
44 | ) external;
45 | }
46 |
--------------------------------------------------------------------------------
/src/interfaces/ISubscribeNFT.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { ISubscribeNFTEvents } from "./ISubscribeNFTEvents.sol";
6 |
7 | interface ISubscribeNFT is ISubscribeNFTEvents {
8 | /**
9 | * @notice Mints the Subscribe NFT.
10 | *
11 | * @param to The recipient address.
12 | * @return uint256 The token id.
13 | */
14 | function mint(address to) external returns (uint256);
15 |
16 | /**
17 | * @notice Initializes the Subscribe NFT.
18 | *
19 | * @param profileId The profile ID to set for the Subscribe NFT.
20 | * @param name The name for the Subscribe NFT.
21 | * @param symbol The symbol for the Subscribe NFT.
22 | */
23 | function initialize(
24 | uint256 profileId,
25 | string calldata name,
26 | string calldata symbol
27 | ) external;
28 | }
29 |
--------------------------------------------------------------------------------
/src/interfaces/ISubscribeNFTEvents.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | interface ISubscribeNFTEvents {
6 | /**
7 | * @notice Emiited when the subscribe NFT is initialized
8 | *
9 | * @param profileId The profile ID for the Susbcribe NFT.
10 | * @param name The name for the Subscribe NFT.
11 | * @param symbol The symbol for the Subscribe NFT.
12 | */
13 | event Initialize(uint256 indexed profileId, string name, string symbol);
14 | }
15 |
--------------------------------------------------------------------------------
/src/interfaces/ITreasury.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { ITreasuryEvents } from "../interfaces/ITreasuryEvents.sol";
6 |
7 | interface ITreasury is ITreasuryEvents {
8 | /**
9 | * @notice Gets the treasury address.
10 | *
11 | * @return address The treasury address.
12 | */
13 | function getTreasuryAddress() external view returns (address);
14 |
15 | /**
16 | * @notice Gets the treasury fee. The percentage is calculated as: treasuryFee/_MAX_BPS.
17 | *
18 | * @return address The treasury fee.
19 | */
20 | function getTreasuryFee() external view returns (uint256);
21 |
22 | /**
23 | * @notice Checks if the currency is allowed.
24 | *
25 | * @return bool The status of allowance for the currency.
26 | */
27 | function isCurrencyAllowed(address currency) external view returns (bool);
28 | }
29 |
--------------------------------------------------------------------------------
/src/interfaces/ITreasuryEvents.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { DataTypes } from "../libraries/DataTypes.sol";
6 |
7 | interface ITreasuryEvents {
8 | /**
9 | * @notice Emitted when a currency has been allowed.
10 | *
11 | * @param currency The ERC20 token contract address.
12 | * @param preAllowed The previously allow state.
13 | * @param newAllowed The newly set allow state.
14 | */
15 | event AllowCurrency(
16 | address indexed currency,
17 | bool indexed preAllowed,
18 | bool indexed newAllowed
19 | );
20 |
21 | /**
22 | * @notice Emitted when a new treasuryAddress has been set.
23 | *
24 | * @param preTreasuryAddress The previous treasuryAddress.
25 | * @param treasuryAddress The new treasuryAddress.
26 | */
27 | event SetTreasuryAddress(
28 | address indexed preTreasuryAddress,
29 | address indexed treasuryAddress
30 | );
31 |
32 | /**
33 | * @notice Emitted when a new treasuryFee has been set.
34 | *
35 | * @param preTreasuryFee The previous treasuryFee.
36 | * @param treasuryFee The new treasuryFee.
37 | */
38 | event SetTreasuryFee(
39 | uint16 indexed preTreasuryFee,
40 | uint16 indexed treasuryFee
41 | );
42 | }
43 |
--------------------------------------------------------------------------------
/src/interfaces/IUpgradeable.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | interface IUpgradeable {
6 | /**
7 | * @notice Contract version number.
8 | *
9 | * @return uint256 The version number.
10 | */
11 | function version() external pure returns (uint256);
12 | }
13 |
--------------------------------------------------------------------------------
/src/middlewares/base/FeeMw.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { ITreasury } from "../../interfaces/ITreasury.sol";
6 |
7 | abstract contract FeeMw {
8 | /*//////////////////////////////////////////////////////////////
9 | STATES
10 | //////////////////////////////////////////////////////////////*/
11 | address public immutable TREASURY; // solhint-disable-line
12 |
13 | /*//////////////////////////////////////////////////////////////
14 | CONSTRUCTOR
15 | //////////////////////////////////////////////////////////////*/
16 |
17 | constructor(address treasury) {
18 | require(treasury != address(0), "ZERO_TREASURY_ADDRESS");
19 | TREASURY = treasury;
20 | }
21 |
22 | /*//////////////////////////////////////////////////////////////
23 | INTERNAL
24 | //////////////////////////////////////////////////////////////*/
25 |
26 | function _currencyAllowed(address currency) internal view returns (bool) {
27 | return ITreasury(TREASURY).isCurrencyAllowed(currency);
28 | }
29 |
30 | function _treasuryAddress() internal view returns (address) {
31 | return ITreasury(TREASURY).getTreasuryAddress();
32 | }
33 |
34 | function _treasuryFee() internal view returns (uint256) {
35 | return ITreasury(TREASURY).getTreasuryFee();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/middlewares/base/PermissionedMw.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { ICyberEngine } from "../../interfaces/ICyberEngine.sol";
6 |
7 | abstract contract PermissionedMw {
8 | /*//////////////////////////////////////////////////////////////
9 | STATES
10 | //////////////////////////////////////////////////////////////*/
11 | address public immutable ENGINE; // solhint-disable-line
12 |
13 | /*//////////////////////////////////////////////////////////////
14 | MODIFIERS
15 | //////////////////////////////////////////////////////////////*/
16 |
17 | /**
18 | * @notice Checks that the sender is the engine address.
19 | */
20 | modifier onlyEngine() {
21 | require(ENGINE == msg.sender, "NON_ENGINE_ADDRESS");
22 | _;
23 | }
24 |
25 | /*//////////////////////////////////////////////////////////////
26 | CONSTRUCTOR
27 | //////////////////////////////////////////////////////////////*/
28 |
29 | constructor(address engine) {
30 | require(engine != address(0), "ENGINE_ADDRESS_ZERO");
31 | ENGINE = engine;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/middlewares/essence/CollectDisallowedMw.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { IEssenceMiddleware } from "../../interfaces/IEssenceMiddleware.sol";
6 |
7 | /**
8 | * @title Collect Disallowed Middleware
9 | * @author CyberConnect
10 | * @notice This contract is a middleware to disallow any collection to the essence that uses it.
11 | */
12 | contract CollectDisallowedMw is IEssenceMiddleware {
13 | /*//////////////////////////////////////////////////////////////
14 | EXTERNAL
15 | //////////////////////////////////////////////////////////////*/
16 |
17 | /// @inheritdoc IEssenceMiddleware
18 | function setEssenceMwData(
19 | uint256,
20 | uint256,
21 | bytes calldata
22 | ) external pure returns (bytes memory) {
23 | // do nothing
24 | return new bytes(0);
25 | }
26 |
27 | /**
28 | * @inheritdoc IEssenceMiddleware
29 | * @notice This process denies any attempts to collect the essence
30 | */
31 | function preProcess(
32 | uint256,
33 | uint256,
34 | address,
35 | address,
36 | bytes calldata
37 | ) external pure override {
38 | revert("COLLECT_DISALLOWED");
39 | }
40 |
41 | /// @inheritdoc IEssenceMiddleware
42 | function postProcess(
43 | uint256,
44 | uint256,
45 | address,
46 | address,
47 | bytes calldata
48 | ) external {
49 | // do nothing
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/middlewares/essence/CollectOnlySubscribedMw.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { ERC721 } from "../../dependencies/solmate/ERC721.sol";
6 |
7 | import { IEssenceMiddleware } from "../../interfaces/IEssenceMiddleware.sol";
8 | import { IProfileNFT } from "../../interfaces/IProfileNFT.sol";
9 |
10 | /**
11 | * @title Collect only when subscribed Middleware
12 | * @author CyberConnect
13 | * @notice This contract is a middleware to allow the address to collect an essence only if they are subscribed
14 | */
15 | contract CollectOnlySubscribedMw is IEssenceMiddleware {
16 | /*//////////////////////////////////////////////////////////////
17 | EXTERNAL VIEW
18 | //////////////////////////////////////////////////////////////*/
19 |
20 | /// @inheritdoc IEssenceMiddleware
21 | function setEssenceMwData(
22 | uint256,
23 | uint256,
24 | bytes calldata
25 | ) external pure returns (bytes memory) {
26 | // do nothing
27 | return new bytes(0);
28 | }
29 |
30 | /**
31 | * @inheritdoc IEssenceMiddleware
32 | * @notice Process that checks if the user is already subscribed to the essence owner
33 | */
34 | function preProcess(
35 | uint256 profileId,
36 | uint256,
37 | address collector,
38 | address,
39 | bytes calldata
40 | ) external view override {
41 | require(
42 | _checkSubscribe(msg.sender, profileId, collector),
43 | "NOT_SUBSCRIBED"
44 | );
45 | }
46 |
47 | /// @inheritdoc IEssenceMiddleware
48 | function postProcess(
49 | uint256,
50 | uint256,
51 | address,
52 | address,
53 | bytes calldata
54 | ) external {
55 | // do nothing
56 | }
57 |
58 | /*//////////////////////////////////////////////////////////////
59 | INTERNAL
60 | //////////////////////////////////////////////////////////////*/
61 |
62 | function _checkSubscribe(
63 | address namespace,
64 | uint256 profileId,
65 | address collector
66 | ) internal view returns (bool) {
67 | address essenceOwnerSubscribeNFT = IProfileNFT(namespace)
68 | .getSubscribeNFT(profileId);
69 |
70 | return (essenceOwnerSubscribeNFT != address(0) &&
71 | ERC721(essenceOwnerSubscribeNFT).balanceOf(collector) != 0);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/middlewares/subscribe/SubscribeDisallowedMw.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { ISubscribeMiddleware } from "../../interfaces/ISubscribeMiddleware.sol";
6 |
7 | /**
8 | * @title Subscribe Disallowed Middleware
9 | * @author CyberConnect
10 | * @notice This contract is a middleware to disallow any subscriptions to the user.
11 | */
12 | contract SubscribeDisallowedMw is ISubscribeMiddleware {
13 | /*//////////////////////////////////////////////////////////////
14 | EXTERNAL VIEW
15 | //////////////////////////////////////////////////////////////*/
16 |
17 | /// @inheritdoc ISubscribeMiddleware
18 | function setSubscribeMwData(uint256, bytes calldata)
19 | external
20 | pure
21 | override
22 | returns (bytes memory)
23 | {
24 | // do nothing
25 | return new bytes(0);
26 | }
27 |
28 | /**
29 | * @inheritdoc ISubscribeMiddleware
30 | * @notice Process that disallows a subscription
31 | */
32 | function preProcess(
33 | uint256,
34 | address,
35 | address,
36 | bytes calldata
37 | ) external pure override {
38 | revert("SUBSCRIBE_DISALLOWED");
39 | }
40 |
41 | /// @inheritdoc ISubscribeMiddleware
42 | function postProcess(
43 | uint256 profileId,
44 | address subscriber,
45 | address subscribeNFT,
46 | bytes calldata data
47 | ) external override {
48 | // do nothing
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/middlewares/subscribe/SubscribeOnlyOnceMw.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { ERC721 } from "../../dependencies/solmate/ERC721.sol";
6 |
7 | import { ISubscribeMiddleware } from "../../interfaces/ISubscribeMiddleware.sol";
8 |
9 | /**
10 | * @title Subscribe Only Once Middleware
11 | * @author CyberConnect
12 | * @notice This contract is a middleware to allow the address to subscribe only once to another address.
13 | */
14 | contract SubscribeOnlyOnceMw is ISubscribeMiddleware {
15 | /*//////////////////////////////////////////////////////////////
16 | EXTERNAL VIEW
17 | //////////////////////////////////////////////////////////////*/
18 |
19 | /// @inheritdoc ISubscribeMiddleware
20 | function setSubscribeMwData(uint256, bytes calldata)
21 | external
22 | pure
23 | override
24 | returns (bytes memory)
25 | {
26 | // do nothing
27 | return new bytes(0);
28 | }
29 |
30 | /**
31 | * @inheritdoc ISubscribeMiddleware
32 | * @notice Process that checks if the subscriber is already subscribed.
33 | */
34 | function preProcess(
35 | uint256,
36 | address subscriber,
37 | address subscribeNFT,
38 | bytes calldata
39 | ) external view override {
40 | require(
41 | ERC721(subscribeNFT).balanceOf(subscriber) == 0,
42 | "Already subscribed"
43 | );
44 | }
45 |
46 | /// @inheritdoc ISubscribeMiddleware
47 | function postProcess(
48 | uint256 profileId,
49 | address subscriber,
50 | address subscribeNFT,
51 | bytes calldata data
52 | ) external override {
53 | // do nothing
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/periphery/RelationshipChecker.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { IERC721 } from "openzeppelin-contracts/contracts/token/ERC721/IERC721.sol";
6 |
7 | import { IProfileNFT } from "../interfaces/IProfileNFT.sol";
8 |
9 | contract RelationshipChecker {
10 | address internal _namespace;
11 |
12 | /*//////////////////////////////////////////////////////////////
13 | CONSTRUCTOR
14 | //////////////////////////////////////////////////////////////*/
15 |
16 | constructor(address namespace) {
17 | _namespace = namespace;
18 | }
19 |
20 | /*//////////////////////////////////////////////////////////////
21 | EXTERNAL VIEW
22 | //////////////////////////////////////////////////////////////*/
23 |
24 | /**
25 | * @notice Check if the profile issued EssenceNFT is collected by me.
26 | *
27 | * @param profileId The profile id.
28 | * @param essenceId The essence id.
29 | * @param me The address to check.
30 | */
31 | function isCollectedByMe(
32 | uint256 profileId,
33 | uint256 essenceId,
34 | address me
35 | ) external view returns (bool) {
36 | address essNFTAddr = IProfileNFT(_namespace).getEssenceNFT(
37 | profileId,
38 | essenceId
39 | );
40 | if (essNFTAddr == address(0)) {
41 | return false;
42 | }
43 |
44 | return IERC721(essNFTAddr).balanceOf(me) > 0;
45 | }
46 |
47 | /**
48 | * @notice Check if the profile is subscribed by me.
49 | *
50 | * @param profileId The profile id.
51 | * @param me The address to check.
52 | */
53 | function isSubscribedByMe(uint256 profileId, address me)
54 | external
55 | view
56 | returns (bool)
57 | {
58 | address subNFTAddr = IProfileNFT(_namespace).getSubscribeNFT(profileId);
59 | if (subNFTAddr == address(0)) {
60 | return false;
61 | }
62 | return IERC721(subNFTAddr).balanceOf(me) > 0;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/storages/CyberBoxNFTStorage.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | abstract contract CyberBoxNFTStorage {
6 | // constant
7 | uint256 internal constant _VERSION = 1;
8 |
9 | // storage
10 | address internal _signer;
11 | }
12 |
--------------------------------------------------------------------------------
/src/storages/CyberEngineStorage.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { DataTypes } from "../libraries/DataTypes.sol";
6 |
7 | abstract contract CyberEngineStorage {
8 | // constant
9 | string internal constant _VERSION_STRING = "1"; // for 712, should never change
10 | uint256 internal constant _VERSION = 2;
11 |
12 | // storage
13 | mapping(address => bool) internal _profileMwAllowlist;
14 | mapping(address => bool) internal _essenceMwAllowlist;
15 | mapping(address => bool) internal _subscribeMwAllowlist;
16 | mapping(bytes32 => address) internal _namespaceByName;
17 | mapping(address => DataTypes.NamespaceStruct) internal _namespaceInfo;
18 | }
19 |
--------------------------------------------------------------------------------
/src/storages/CyberGrandNFTStorage.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | abstract contract CyberGrandNFTStorage {
6 | // constant
7 | uint256 internal constant _VERSION = 1;
8 |
9 | // storage
10 | address internal _signer;
11 | string internal _tokenURI;
12 | }
13 |
--------------------------------------------------------------------------------
/src/storages/EssenceNFTStorage.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | contract EssenceNFTStorage {
6 | // constant
7 | uint256 internal constant _VERSION = 2;
8 |
9 | // storage
10 | uint256 internal _profileId;
11 | uint256 internal _essenceId;
12 | bool internal _transferable;
13 | }
14 |
--------------------------------------------------------------------------------
/src/storages/Link3ProfileDescriptorStorage.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | contract Link3ProfileDescriptorStorage {
6 | // constant
7 | string internal constant _BASE_URL = "https://link3.to/";
8 | uint256 internal constant _VERSION = 1;
9 |
10 | // storage
11 | string public animationTemplate;
12 | }
13 |
--------------------------------------------------------------------------------
/src/storages/Link3ProfileDescriptorStorageV2.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | contract Link3ProfileDescriptorStorageV2 {
6 | // constant
7 | string internal constant _BASE_URL = "https://link3.to/";
8 | uint256 internal constant _VERSION = 1;
9 | }
10 |
--------------------------------------------------------------------------------
/src/storages/MBNFTStorage.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | abstract contract MBNFTStorage {
6 | // constant
7 | uint256 internal constant _VERSION = 1;
8 |
9 | // storage
10 | string internal _tokenURI;
11 | address internal _boxAddr;
12 | }
13 |
--------------------------------------------------------------------------------
/src/storages/ProfileNFTStorage.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { DataTypes } from "../libraries/DataTypes.sol";
6 |
7 | abstract contract ProfileNFTStorage {
8 | // constant
9 | uint256 internal constant _VERSION = 2;
10 |
11 | // storage
12 | address internal _nftDescriptor;
13 | address internal _namespaceOwner;
14 | mapping(uint256 => DataTypes.ProfileStruct) internal _profileById;
15 | mapping(bytes32 => uint256) internal _profileIdByHandleHash;
16 | mapping(uint256 => string) internal _metadataById;
17 | mapping(uint256 => mapping(address => bool)) internal _operatorApproval;
18 | mapping(address => uint256) internal _addressToPrimaryProfile;
19 | mapping(uint256 => DataTypes.SubscribeStruct)
20 | internal _subscribeByProfileId;
21 | mapping(uint256 => mapping(uint256 => DataTypes.EssenceStruct))
22 | internal _essenceByIdByProfileId;
23 | }
24 |
--------------------------------------------------------------------------------
/src/storages/SubscribeNFTStorage.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | abstract contract SubscribeNFTStorage {
6 | // storage
7 | uint256 internal _profileId;
8 | uint256 internal constant _VERSION = 2;
9 | }
10 |
--------------------------------------------------------------------------------
/src/token/CYBER.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { ERC20 } from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
6 | import { ERC20Permit } from "openzeppelin-contracts/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";
7 | import { Ownable } from "openzeppelin-contracts/contracts/access/Ownable.sol";
8 |
9 | contract CYBER is ERC20, ERC20Permit, Ownable {
10 | // Total supply of cyber token is 100M
11 | uint256 public TOTAL_SUPPLY = 100_000_000 * 10**uint256(decimals());
12 |
13 | constructor(address owner, address to)
14 | ERC20("CyberConnect", "CYBER")
15 | ERC20Permit("CyberConnect")
16 | {
17 | _transferOwnership(owner);
18 |
19 | _mint(to, TOTAL_SUPPLY);
20 | }
21 |
22 | function mint(address to, uint256 amount) external onlyOwner {
23 | _mint(to, amount);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/upgradeability/UpgradeableBeacon.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 | // OpenZeppelin Contracts v4.4.1 (proxy/beacon/UpgradeableBeacon.sol)
3 |
4 | pragma solidity ^0.8.0;
5 |
6 | import "openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol";
7 | import "openzeppelin-contracts/contracts/utils/Address.sol";
8 |
9 | /**
10 | * @dev Adapted from Openzepelin's UpgradeableBeacon.sol with RolesAuthority auth
11 | *
12 | * @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their
13 | * implementation contract, which is where they will delegate all function calls.
14 | *
15 | * An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.
16 | */
17 | contract UpgradeableBeacon is IBeacon {
18 | address private _implementation;
19 | address public immutable OWNER;
20 |
21 | /**
22 | * @dev Emitted when the implementation returned by the beacon is changed.
23 | */
24 | event Upgraded(address indexed implementation);
25 |
26 | /**
27 | * @dev Sets the address of the initial implementation, and the owner can upgrade the
28 | * beacon.
29 | */
30 | constructor(address implementation_, address owner) {
31 | require(owner != address(0), "ZERO_OWNER_ADDRESS");
32 | _setImplementation(implementation_);
33 | OWNER = owner;
34 | }
35 |
36 | /**
37 | * @dev Returns the current implementation address.
38 | */
39 | function implementation() public view virtual override returns (address) {
40 | return _implementation;
41 | }
42 |
43 | /**
44 | * @dev Upgrades the beacon to a new implementation.
45 | *
46 | * Emits an {Upgraded} event.
47 | *
48 | * Requirements:
49 | *
50 | * - msg.sender must be the owner of the contract.
51 | * - `newImplementation` must be a contract.
52 | */
53 | function upgradeTo(address newImplementation) public virtual {
54 | require(msg.sender == address(OWNER), "ONLY_OWNER");
55 | _setImplementation(newImplementation);
56 | emit Upgraded(newImplementation);
57 | }
58 |
59 | /**
60 | * @dev Sets the implementation contract address for this beacon
61 | *
62 | * Requirements:
63 | *
64 | * - `newImplementation` must be a contract.
65 | */
66 | function _setImplementation(address newImplementation) private {
67 | require(Address.isContract(newImplementation), "UpgradeableBeacon: implementation is not a contract");
68 | _implementation = newImplementation;
69 | }
70 | }
--------------------------------------------------------------------------------
/test/Deployer.t.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Test.sol";
6 |
7 | import { ProfileDeployer } from "../src/deployer/ProfileDeployer.sol";
8 | import { SubscribeDeployer } from "../src/deployer/SubscribeDeployer.sol";
9 | import { EssenceDeployer } from "../src/deployer/EssenceDeployer.sol";
10 |
11 | contract DeployerTest is Test {
12 | ProfileDeployer pd;
13 | SubscribeDeployer sd;
14 | EssenceDeployer ed;
15 | bytes32 salt = keccak256(bytes("salt"));
16 |
17 | function setUp() public {
18 | pd = new ProfileDeployer();
19 | sd = new SubscribeDeployer();
20 | ed = new EssenceDeployer();
21 | }
22 |
23 | function testCannotDeploySubcribeWithZeroProfile() public {
24 | vm.expectRevert("ZERO_ADDRESS");
25 | sd.deploySubscribe(salt, address(0));
26 | }
27 |
28 | function testCannotDeployEssenceWithZeroProfile() public {
29 | vm.expectRevert("ZERO_ADDRESS");
30 | ed.deployEssence(salt, address(0));
31 | }
32 |
33 | function testCannotDeployProfileWithZeroEngine() public {
34 | vm.expectRevert("ENGINE_NOT_SET");
35 | pd.deployProfile(salt, address(0), address(0xdead), address(0xdead));
36 | }
37 |
38 | function testCannotDeployProfileWithZeroSubscribe() public {
39 | vm.expectRevert("SUBSCRIBE_BEACON_NOT_SET");
40 | pd.deployProfile(salt, address(0xdead), address(0), address(0xdead));
41 | }
42 |
43 | function testCannotDeployProfileWithZeroEssence() public {
44 | vm.expectRevert("ESSENCE_BEACON_NOT_SET");
45 | pd.deployProfile(salt, address(0xdead), address(0xdead), address(0));
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/test/Pausable.t.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Test.sol";
6 |
7 | import { MockPausable } from "./utils/MockPausable.sol";
8 |
9 | contract PausableTest is Test {
10 | event Paused(address account);
11 | event Unpaused(address account);
12 |
13 | MockPausable internal pausableContract;
14 |
15 | function setUp() public {
16 | pausableContract = new MockPausable();
17 | }
18 |
19 | function testcanPerformNormalProcessInNonPause() public {
20 | assertEq(pausableContract.count(), 0);
21 | pausableContract.normalProcess();
22 | assertEq(pausableContract.count(), 1);
23 | }
24 |
25 | function testCannotTakeDrasticMeasureInNonPause() public {
26 | vm.expectRevert("Pausable: not paused");
27 | pausableContract.drasticMeasure();
28 | }
29 |
30 | function testEmitPauseEvent() public {
31 | vm.expectEmit(true, false, false, true);
32 | emit Paused(address(this));
33 | pausableContract.pause();
34 | }
35 |
36 | function testCannotPerformNormalProcessInPause() public {
37 | pausableContract.pause();
38 | vm.expectRevert("Pausable: paused");
39 | pausableContract.normalProcess();
40 | }
41 |
42 | function testCanTakeADrasticMeasureInAPause() public {
43 | pausableContract.pause();
44 | pausableContract.drasticMeasure();
45 | assertEq(pausableContract.drasticMeasureTaken(), true);
46 | }
47 |
48 | function testCannotRepause() public {
49 | pausableContract.pause();
50 | vm.expectRevert("Pausable: paused");
51 | pausableContract.pause();
52 | }
53 |
54 | function testIsUnpausableByThePauser() public {
55 | pausableContract.pause();
56 | pausableContract.unpause();
57 | assertEq(pausableContract.paused(), false);
58 | }
59 |
60 | function testUnPausedEvent() public {
61 | pausableContract.pause();
62 | vm.expectEmit(true, false, false, true);
63 | emit Unpaused(address(this));
64 | pausableContract.unpause();
65 | }
66 |
67 | function shouldResumeAllowingNormalProcess() public {
68 | pausableContract.pause();
69 | pausableContract.unpause();
70 | assertEq(pausableContract.count(), 0);
71 | pausableContract.normalProcess();
72 | assertEq(pausableContract.count(), 1);
73 | }
74 |
75 | function testShouldPreventDrasticMeasure() public {
76 | pausableContract.pause();
77 | pausableContract.unpause();
78 | vm.expectRevert("Pausable: not paused");
79 | pausableContract.drasticMeasure();
80 | }
81 |
82 | function testCannotReUnpause() public {
83 | pausableContract.pause();
84 | pausableContract.unpause();
85 | vm.expectRevert("Pausable: not paused");
86 | pausableContract.unpause();
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/test/SubscribeNFTUpgrade.t.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Test.sol";
6 | import { BeaconProxy } from "openzeppelin-contracts/contracts/proxy/beacon/BeaconProxy.sol";
7 |
8 | import { MockSubscribeNFTV2 } from "./utils/MockSubscribeNFTV2.sol";
9 | import { TestDeployer } from "./utils/TestDeployer.sol";
10 | import { UpgradeableBeacon } from "../src/upgradeability/UpgradeableBeacon.sol";
11 | import { SubscribeNFT } from "../src/core/SubscribeNFT.sol";
12 |
13 | contract SubscribeNFTUpgradeTest is Test, TestDeployer {
14 | UpgradeableBeacon internal beacon;
15 | BeaconProxy internal proxy;
16 | BeaconProxy internal proxyB;
17 | address internal profile;
18 |
19 | uint256 internal profileId = 1;
20 | address constant alice = address(0xA11CE);
21 |
22 | function _deployV2(address _profile)
23 | internal
24 | returns (MockSubscribeNFTV2 addr)
25 | {
26 | subParams.profileProxy = _profile;
27 | addr = new MockSubscribeNFTV2{ salt: _salt }();
28 | delete subParams;
29 | }
30 |
31 | function setUp() public {
32 | profile = address(0xdead);
33 | address impl = deploySubscribe(_salt, address(profile));
34 | beacon = new UpgradeableBeacon(impl, address(profile));
35 | bytes memory functionData = abi.encodeWithSelector(
36 | SubscribeNFT.initialize.selector,
37 | profileId,
38 | "name",
39 | "SYMBOL"
40 | );
41 | proxy = new BeaconProxy(address(beacon), functionData);
42 | proxyB = new BeaconProxy(address(beacon), functionData);
43 | }
44 |
45 | function testAuth() public {
46 | assertEq(beacon.OWNER(), address(profile));
47 | }
48 |
49 | function testUpgrade() public {
50 | MockSubscribeNFTV2 implB = _deployV2(profile);
51 |
52 | vm.prank(address(profile));
53 | beacon.upgradeTo(address(implB));
54 |
55 | MockSubscribeNFTV2 p = MockSubscribeNFTV2(address(proxy));
56 | MockSubscribeNFTV2 pB = MockSubscribeNFTV2(address(proxyB));
57 |
58 | assertEq(p.version(), 100);
59 | assertEq(pB.version(), 100);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/test/Treasury.t.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Test.sol";
6 |
7 | import { ITreasuryEvents } from "../src/interfaces/ITreasuryEvents.sol";
8 |
9 | import { Constants } from "../src/libraries/Constants.sol";
10 |
11 | import { Treasury } from "../src/middlewares/base/Treasury.sol";
12 |
13 | contract TreasuryTest is Test, ITreasuryEvents {
14 | Treasury t;
15 | address constant owner = address(0xA11CE);
16 | address constant bob = address(0xB0B);
17 | address constant gov = address(0x8888);
18 | address constant token = address(0x111);
19 |
20 | function setUp() public {
21 | t = new Treasury(owner, bob, 200);
22 | }
23 |
24 | function testBasic() public {
25 | assertEq(t.getTreasuryAddress(), bob);
26 | assertEq(t.getTreasuryFee(), 200);
27 | }
28 |
29 | function testSetTreasuryFee() public {
30 | vm.prank(owner);
31 |
32 | vm.expectEmit(true, true, false, true);
33 | emit SetTreasuryFee(200, 300);
34 |
35 | t.setTreasuryFee(300);
36 | assertEq(t.getTreasuryFee(), 300);
37 | }
38 |
39 | function testCannotSetTreasuryFeeExceedMax() public {
40 | vm.prank(owner);
41 | vm.expectRevert("INVALID_TREASURY_FEE");
42 | t.setTreasuryFee(Constants._MAX_BPS + 1);
43 | }
44 |
45 | function testCannotSetTreasuryFeeNonOwner() public {
46 | vm.expectRevert("UNAUTHORIZED");
47 | t.setTreasuryFee(Constants._MAX_BPS);
48 | }
49 |
50 | function testSetTreasuryAddress() public {
51 | vm.prank(owner);
52 |
53 | vm.expectEmit(true, true, false, true);
54 | emit SetTreasuryAddress(bob, gov);
55 |
56 | t.setTreasuryAddress(gov);
57 | assertEq(t.getTreasuryAddress(), gov);
58 | }
59 |
60 | function testCannotSetTreasuryAddressNonOwner() public {
61 | vm.expectRevert("UNAUTHORIZED");
62 | t.setTreasuryAddress(bob);
63 | }
64 |
65 | function testAllowCurrency() public {
66 | vm.startPrank(owner);
67 | assertEq(t.isCurrencyAllowed(token), false);
68 | t.allowCurrency(token, true);
69 | assertEq(t.isCurrencyAllowed(token), true);
70 | }
71 |
72 | function testCannotAllowCurrencyNonOwner() public {
73 | vm.expectRevert("UNAUTHORIZED");
74 | t.allowCurrency(token, true);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/test/UpgradeableBeacon.t.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Test.sol";
6 | import "openzeppelin-contracts/contracts/mocks/RegressionImplementation.sol";
7 |
8 | import "../src/upgradeability/UpgradeableBeacon.sol";
9 |
10 | contract UpgradeableBeaconTest is Test {
11 | address internal owner = address(0xA11CE);
12 | address internal other = address(0xB0B);
13 | event Upgraded(address indexed implementation);
14 | Implementation1 v1;
15 | UpgradeableBeacon beacon;
16 |
17 | function setUp() public {
18 | v1 = new Implementation1();
19 | beacon = new UpgradeableBeacon(address(v1), owner);
20 | }
21 |
22 | function testCannotCreatedWithNonContractImplementation() public {
23 | vm.expectRevert("UpgradeableBeacon: implementation is not a contract");
24 | new UpgradeableBeacon(owner, address(this));
25 | }
26 |
27 | function testReturnsImplementation() public {
28 | assertEq(beacon.implementation(), address(v1));
29 | }
30 |
31 | function testCanBeUpgradedByTheOwner() public {
32 | Implementation2 v2 = new Implementation2();
33 | vm.prank(owner);
34 | vm.expectEmit(true, false, false, true);
35 | emit Upgraded(address(v2));
36 | beacon.upgradeTo(address(v2));
37 | assertEq(beacon.implementation(), address(v2));
38 | }
39 |
40 | function testCannotUpgradeByNonContract() public {
41 | vm.expectRevert("ONLY_OWNER");
42 | beacon.upgradeTo(other);
43 | }
44 |
45 | function testCannotUpgradeByOtherAccount() public {
46 | Implementation2 v2 = new Implementation2();
47 | vm.expectRevert("ONLY_OWNER");
48 | beacon.upgradeTo(address(v2));
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/test/integration/IntegrationBase.t.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 | import { LibDeploy } from "../../script/libraries/LibDeploy.sol";
5 | import { RolesAuthority } from "../../src/dependencies/solmate/RolesAuthority.sol";
6 | import { ERC1967Proxy } from "openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol";
7 | import { IProfileNFTEvents } from "../../src/interfaces/IProfileNFTEvents.sol";
8 | import { ProfileNFT } from "../../src/core/ProfileNFT.sol";
9 | import { TestLibFixture } from "../utils/TestLibFixture.sol";
10 | import { Base64 } from "openzeppelin-contracts/contracts/utils/Base64.sol";
11 | import { LibString } from "../../src/libraries/LibString.sol";
12 | import { Link3ProfileDescriptor } from "../../src/periphery/Link3ProfileDescriptor.sol";
13 | import { PermissionedFeeCreationMw } from "../../src/middlewares/profile/PermissionedFeeCreationMw.sol";
14 | import { TestIntegrationBase } from "../utils/TestIntegrationBase.sol";
15 |
16 | contract IntegrationBaseTest is TestIntegrationBase, IProfileNFTEvents {
17 | function setUp() public {
18 | _setUp();
19 | }
20 |
21 | function testRegistrationTwice() public {
22 | assertEq(profileMw.getSigner(address(link3Profile)), link3Signer);
23 | string memory handle = "bob";
24 | address to = bob;
25 | // Register bob profile
26 | vm.expectEmit(true, true, false, true);
27 | emit SetPrimaryProfile(to, 2); // hardcode profileid
28 | uint256 bobProfileId = TestLibFixture.registerProfile(
29 | vm,
30 | link3Profile,
31 | profileMw,
32 | handle,
33 | to,
34 | link3SignerPk
35 | );
36 |
37 | // check bob profile details
38 | string memory gotHandle = link3Profile.getHandleByProfileId(
39 | bobProfileId
40 | );
41 | string memory avatar = link3Profile.getAvatar(bobProfileId);
42 | string memory metadata = link3Profile.getMetadata(bobProfileId);
43 | address descriptor = link3Profile.getNFTDescriptor();
44 | assertEq(gotHandle, handle);
45 | assertEq(avatar, "avatar");
46 | assertEq(metadata, "metadata");
47 |
48 | // check bob balance
49 | assertEq(link3Profile.balanceOf(to), 1);
50 |
51 | // check bob profile ownership
52 | assertEq(link3Profile.ownerOf(bobProfileId), to);
53 |
54 | assertEq(link3Profile.getPrimaryProfile(to), bobProfileId);
55 | assertEq(link3Profile.getPrimaryProfile(to), bobProfileId);
56 |
57 | // register second time will not set primary profile
58 | uint256 secondId = TestLibFixture.registerProfile(
59 | vm,
60 | link3Profile,
61 | profileMw,
62 | "handle2",
63 | to,
64 | link3SignerPk
65 | );
66 | assertEq(secondId, 3);
67 |
68 | // primary profile is still 2
69 | assertEq(link3Profile.getPrimaryProfile(to), 2);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/test/integration/middleware/subscribe/SubscribeOnlyOnceMw.t.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Test.sol";
6 |
7 | import { IProfileNFTEvents } from "../../../../src/interfaces/IProfileNFTEvents.sol";
8 |
9 | import { LibDeploy } from "../../../../script/libraries/LibDeploy.sol";
10 | import { Constants } from "../../../../src/libraries/Constants.sol";
11 | import { DataTypes } from "../../../../src/libraries/DataTypes.sol";
12 |
13 | import { TestLibFixture } from "../../../utils/TestLibFixture.sol";
14 | import { SubscribeOnlyOnceMw } from "../../../../src/middlewares/subscribe/SubscribeOnlyOnceMw.sol";
15 | import { ProfileNFT } from "../../../../src/core/ProfileNFT.sol";
16 | import { TestIntegrationBase } from "../../../utils/TestIntegrationBase.sol";
17 |
18 | contract SubscribeOnlyOnceMwTest is TestIntegrationBase, IProfileNFTEvents {
19 | uint256 bobProfileId;
20 | address profileDescriptorAddress;
21 | SubscribeOnlyOnceMw subMw;
22 |
23 | event Transfer(
24 | address indexed from,
25 | address indexed to,
26 | uint256 indexed id
27 | );
28 |
29 | function setUp() public {
30 | _setUp();
31 | subMw = new SubscribeOnlyOnceMw();
32 | vm.label(address(subMw), "SubscribeMiddleware");
33 | string memory handle = "bob";
34 | address to = bob;
35 | string memory uri = "uri";
36 |
37 | bobProfileId = TestLibFixture.registerProfile(
38 | vm,
39 | link3Profile,
40 | profileMw,
41 | handle,
42 | to,
43 | link3SignerPk
44 | );
45 |
46 | engine.allowSubscribeMw(address(subMw), true);
47 | vm.prank(bob);
48 | link3Profile.setSubscribeData(
49 | bobProfileId,
50 | uri,
51 | address(subMw),
52 | new bytes(0)
53 | );
54 | }
55 |
56 | function testSubscribeOnlyOnce() public {
57 | uint256[] memory ids = new uint256[](1);
58 | ids[0] = bobProfileId;
59 | bytes[] memory data = new bytes[](1);
60 |
61 | address subscribeProxy = getDeployedSubProxyAddress(
62 | addrs.subBeacon,
63 | bobProfileId,
64 | address(link3Profile),
65 | "bob"
66 | );
67 | vm.expectEmit(true, true, false, true, address(link3Profile));
68 | emit DeploySubscribeNFT(bobProfileId, address(subscribeProxy));
69 |
70 | vm.expectEmit(true, true, true, true, address(subscribeProxy));
71 | emit Transfer(address(0), alice, 1);
72 |
73 | vm.expectEmit(true, false, false, true, address(link3Profile));
74 | emit Subscribe(alice, ids, data, data);
75 |
76 | vm.prank(alice);
77 | link3Profile.subscribe(DataTypes.SubscribeParams(ids), data, data);
78 |
79 | assertEq(link3Profile.getSubscribeNFT(bobProfileId), subscribeProxy);
80 |
81 | // Second subscribe will fail
82 | vm.expectRevert("Already subscribed");
83 | vm.prank(alice);
84 | link3Profile.subscribe(DataTypes.SubscribeParams(ids), data, data);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/test/periphery/CyberBoxNFTUpgrade.t.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Test.sol";
6 | import { ERC1967Proxy } from "openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol";
7 |
8 | import { ICyberBoxEvents } from "../../src/interfaces/ICyberBoxEvents.sol";
9 |
10 | import { Constants } from "../../src/libraries/Constants.sol";
11 |
12 | import { MockCyberBoxV2 } from "../utils/MockCyberBoxV2.sol";
13 | import { CyberBoxNFT } from "../../src/periphery/CyberBoxNFT.sol";
14 |
15 | contract CyberBoxNFTUpgradeTest is Test, ICyberBoxEvents {
16 | CyberBoxNFT internal cyberBox;
17 | address constant owner = address(0xe);
18 |
19 | function setUp() public {
20 | CyberBoxNFT impl = new CyberBoxNFT();
21 | bytes memory data = abi.encodeWithSelector(
22 | CyberBoxNFT.initialize.selector,
23 | owner,
24 | owner,
25 | "TestBox",
26 | "TB"
27 | );
28 | ERC1967Proxy proxy = new ERC1967Proxy(address(impl), data);
29 | cyberBox = CyberBoxNFT(address(proxy));
30 | }
31 |
32 | function testCannotUpgradeToAndCallAsNonOwner() public {
33 | assertEq(CyberBoxNFT(address(cyberBox)).version(), 1);
34 | MockCyberBoxV2 implV2 = new MockCyberBoxV2();
35 |
36 | vm.expectRevert("UNAUTHORIZED");
37 | CyberBoxNFT(address(cyberBox)).upgradeToAndCall(
38 | address(implV2),
39 | abi.encodeWithSelector(MockCyberBoxV2.version.selector)
40 | );
41 | assertEq(CyberBoxNFT(address(cyberBox)).version(), 1);
42 | }
43 |
44 | function testCannotUpgradeAsNonOwner() public {
45 | assertEq(CyberBoxNFT(address(cyberBox)).version(), 1);
46 | MockCyberBoxV2 implV2 = new MockCyberBoxV2();
47 |
48 | vm.expectRevert("UNAUTHORIZED");
49 | CyberBoxNFT(address(cyberBox)).upgradeTo(address(implV2));
50 | assertEq(CyberBoxNFT(address(cyberBox)).version(), 1);
51 | }
52 |
53 | function testUpgrade() public {
54 | assertEq(CyberBoxNFT(address(cyberBox)).version(), 1);
55 | MockCyberBoxV2 implV2 = new MockCyberBoxV2();
56 |
57 | vm.prank(owner);
58 | CyberBoxNFT(address(cyberBox)).upgradeTo(address(implV2));
59 | assertEq(CyberBoxNFT(address(cyberBox)).version(), 2);
60 | }
61 |
62 | function testUpgradeToAndCall() public {
63 | assertEq(CyberBoxNFT(address(cyberBox)).version(), 1);
64 | MockCyberBoxV2 implV2 = new MockCyberBoxV2();
65 |
66 | vm.prank(owner);
67 | CyberBoxNFT(address(cyberBox)).upgradeToAndCall(
68 | address(implV2),
69 | abi.encodeWithSelector(MockCyberBoxV2.version.selector)
70 | );
71 | assertEq(CyberBoxNFT(address(cyberBox)).version(), 2);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/test/utils/MockCyberBoxV2.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { CyberBoxNFT } from "../../src/periphery/CyberBoxNFT.sol";
6 |
7 | contract MockCyberBoxV2 is CyberBoxNFT {
8 | function version() external pure override returns (uint256) {
9 | return 2;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/utils/MockERC1155.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol";
6 |
7 | contract MockERC1155 is ERC1155 {
8 | constructor(string memory url) ERC1155(url) {}
9 |
10 | function mint(
11 | address to,
12 | uint256 tokenId,
13 | uint256 amount
14 | ) external {
15 | _mint(to, tokenId, amount, "");
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test/utils/MockERC20.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
6 |
7 | contract MockERC20 is ERC20 {
8 | constructor(string memory name, string memory symbol) ERC20(name, symbol) {
9 | // Mint tokens to msg.sender
10 | // Similar to how
11 | // 1 dollar = 100 cents
12 | // 1 token = 1 * (10 ** decimals)
13 | _mint(msg.sender, 100 * 10**uint256(decimals()));
14 | }
15 |
16 | function mint(address to, uint256 amount) external {
17 | _mint(to, amount);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/test/utils/MockERC721.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "openzeppelin-contracts/contracts/token/ERC721/ERC721.sol";
6 |
7 | contract MockERC721 is ERC721 {
8 | constructor(string memory name, string memory symbol) ERC721(name, symbol) {
9 | // mint four NFT tokens to msg.sender
10 | _mint(msg.sender, 1);
11 | _mint(msg.sender, 2);
12 | _mint(msg.sender, 3);
13 | _mint(msg.sender, 4);
14 | }
15 |
16 | function mint(address to, uint256 tokenId) external {
17 | _mint(to, tokenId);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/test/utils/MockEngine.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { CyberEngine } from "../../src/core/CyberEngine.sol";
6 |
7 | contract MockEngine is CyberEngine {
8 | function setNamespaceInfo(
9 | string calldata name,
10 | address profileMw,
11 | address namespace
12 | ) external {
13 | _namespaceInfo[namespace].name = name;
14 | _namespaceInfo[namespace].profileMw = profileMw;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/test/utils/MockEngineV2.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { CyberEngine } from "../../src/core/CyberEngine.sol";
6 |
7 | contract MockEngineV2 is CyberEngine {
8 | function version() external pure override returns (uint256) {
9 | return 100;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/utils/MockInitializable.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity ^0.8.0;
4 |
5 | import { Initializable } from "openzeppelin-contracts/contracts/proxy/utils/Initializable.sol";
6 |
7 | /**
8 | * @title MockInitializable
9 | * @dev This contract is a mock to test initializable functionality
10 | */
11 | contract MockInitializable is Initializable {
12 | bool public initializerRan;
13 | bool public onlyInitializingRan;
14 | uint256 public x;
15 |
16 | function initialize() public initializer {
17 | initializerRan = true;
18 | }
19 |
20 | function initializeOnlyInitializing() public onlyInitializing {
21 | onlyInitializingRan = true;
22 | }
23 |
24 | function initializerNested() public initializer {
25 | initialize();
26 | }
27 |
28 | function onlyInitializingNested() public initializer {
29 | initializeOnlyInitializing();
30 | }
31 |
32 | function initializeWithX(uint256 _x) public payable initializer {
33 | x = _x;
34 | }
35 |
36 | function nonInitializable(uint256 _x) public payable {
37 | x = _x;
38 | }
39 |
40 | function fail() public pure {
41 | require(false, "InitializableMock forced failure");
42 | }
43 | }
44 |
45 | contract MockConstructorInitializable is Initializable {
46 | bool public initializerRan;
47 | bool public onlyInitializingRan;
48 |
49 | constructor() initializer {
50 | initialize();
51 | initializeOnlyInitializing();
52 | }
53 |
54 | function initialize() public initializer {
55 | initializerRan = true;
56 | }
57 |
58 | function initializeOnlyInitializing() public onlyInitializing {
59 | onlyInitializingRan = true;
60 | }
61 | }
62 |
63 | contract MockChildConstructorInitializable is MockConstructorInitializable {
64 | bool public childInitializerRan;
65 |
66 | constructor() initializer {
67 | childInitialize();
68 | }
69 |
70 | function childInitialize() public initializer {
71 | childInitializerRan = true;
72 | }
73 | }
74 |
75 | contract DisableNew is Initializable {
76 | constructor() {
77 | _disableInitializers();
78 | }
79 | }
80 |
81 | contract DisableOld is Initializable {
82 | constructor() initializer {}
83 | }
84 |
85 | contract DisableBad1 is DisableNew, DisableOld {}
86 |
87 | contract DisableBad2 is Initializable {
88 | constructor() initializer {
89 | _disableInitializers();
90 | }
91 | }
92 |
93 | contract DisableOk is DisableOld, DisableNew {}
94 |
--------------------------------------------------------------------------------
/test/utils/MockLink5NFTDescriptor.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { IProfileNFTDescriptor } from "../../src/interfaces/IProfileNFTDescriptor.sol";
6 |
7 | import { DataTypes } from "../../src/libraries/DataTypes.sol";
8 |
9 | contract MockLink5NFTDescriptor is IProfileNFTDescriptor {
10 | function tokenURI(DataTypes.ConstructTokenURIParams calldata)
11 | external
12 | pure
13 | returns (string memory)
14 | {
15 | return "Link5TokenURI";
16 | }
17 |
18 | function setAnimationTemplate(string calldata template) external {}
19 | }
20 |
--------------------------------------------------------------------------------
/test/utils/MockNFT.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { CyberNFTBase } from "../../src/base/CyberNFTBase.sol";
6 |
7 | contract MockNFT is CyberNFTBase {
8 | function tokenURI(uint256) public pure override returns (string memory) {
9 | return "";
10 | }
11 |
12 | function mint(address _to) public returns (uint256) {
13 | return super._mint(_to);
14 | }
15 |
16 | function initialize(string calldata _name, string calldata _symbol)
17 | external
18 | initializer
19 | {
20 | super._initialize(_name, _symbol);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/test/utils/MockPausable.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity ^0.8.0;
4 |
5 | import { Pausable } from "../../src/dependencies/openzeppelin/Pausable.sol";
6 |
7 | contract MockPausable is Pausable {
8 | bool public drasticMeasureTaken;
9 | uint256 public count;
10 |
11 | constructor() {
12 | drasticMeasureTaken = false;
13 | count = 0;
14 | }
15 |
16 | function normalProcess() external whenNotPaused {
17 | count++;
18 | }
19 |
20 | function drasticMeasure() external whenPaused {
21 | drasticMeasureTaken = true;
22 | }
23 |
24 | function pause() external {
25 | _pause();
26 | }
27 |
28 | function unpause() external {
29 | _unpause();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/test/utils/MockProfile.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { DataTypes } from "../../src/libraries/DataTypes.sol";
6 |
7 | import { ProfileNFT } from "../../src/core/ProfileNFT.sol";
8 |
9 | contract MockProfile is ProfileNFT {
10 | // set internal states for testing
11 | function setSubscribeNFTAddress(uint256 profileId, address subscribeAddr)
12 | external
13 | {
14 | _subscribeByProfileId[profileId].subscribeNFT = subscribeAddr;
15 | }
16 |
17 | // set internal states for testing
18 | function setEssenceNFTAddress(
19 | uint256 profileId,
20 | uint256 essenceId,
21 | address essenceAddr
22 | ) external {
23 | _essenceByIdByProfileId[profileId][essenceId].essenceNFT = essenceAddr;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/test/utils/MockProfileV2.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { ProfileNFT } from "../../src/core/ProfileNFT.sol";
6 |
7 | contract MockProfileV2 is ProfileNFT {
8 | function version() external pure override returns (uint256) {
9 | return 100;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/utils/MockSubscribeNFTV2.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { SubscribeNFT } from "../../src/core/SubscribeNFT.sol";
6 |
7 | contract MockSubscribeNFTV2 is SubscribeNFT {
8 | function version() external pure override returns (uint256) {
9 | return 100;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/utils/TestIntegrationBase.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Test.sol";
6 |
7 | import { ProfileNFT } from "../../src/core/ProfileNFT.sol";
8 | import { CyberEngine } from "../../src/core/CyberEngine.sol";
9 | import { Link3ProfileDescriptor } from "../../src/periphery/Link3ProfileDescriptor.sol";
10 | import { PermissionedFeeCreationMw } from "../../src/middlewares/profile/PermissionedFeeCreationMw.sol";
11 | import { CollectOnlySubscribedMw } from "../../src/middlewares/essence/CollectOnlySubscribedMw.sol";
12 | import { Treasury } from "../../src/middlewares/base/Treasury.sol";
13 |
14 | import { LibDeploy } from "../../script/libraries/LibDeploy.sol";
15 |
16 | import { TestProxy } from "./TestProxy.sol";
17 |
18 | abstract contract TestIntegrationBase is Test, TestProxy {
19 | uint256 internal constant link3SignerPk = 1890;
20 | address internal immutable link3Signer = vm.addr(link3SignerPk);
21 | address internal constant alice = address(0xDEADA11CE);
22 | uint256 internal constant bobPk = 548;
23 | address internal immutable bob = vm.addr(bobPk);
24 | address internal constant carly = address(0xDEADCA11);
25 | address internal constant dixon = address(0xDEADD1);
26 | address internal constant link3Treasury = address(0xDEAD3333);
27 |
28 | address internal constant engineTreasury = address(0xDEADEEEE);
29 |
30 | address link3EssBeacon;
31 | address link3SubBeacon;
32 |
33 | ProfileNFT link3Profile;
34 | Link3ProfileDescriptor profileDescriptor;
35 | PermissionedFeeCreationMw profileMw;
36 | CollectOnlySubscribedMw collectMw;
37 | CyberEngine engine;
38 | Treasury treasury;
39 |
40 | LibDeploy.ContractAddresses addrs;
41 |
42 | function _setUp() internal {
43 | addrs = LibDeploy.deployInTest(
44 | vm,
45 | link3Signer,
46 | link3Treasury,
47 | engineTreasury
48 | );
49 | link3Profile = ProfileNFT(addrs.link3Profile);
50 | profileDescriptor = Link3ProfileDescriptor(addrs.link3DescriptorProxy);
51 | profileMw = PermissionedFeeCreationMw(addrs.link3ProfileMw);
52 | engine = CyberEngine(addrs.engineProxyAddress);
53 | treasury = Treasury(addrs.cyberTreasury);
54 | link3EssBeacon = addrs.essBeacon;
55 | link3SubBeacon = addrs.subBeacon;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/test/utils/TestLib712.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | library TestLib712 {
6 | bytes32 private constant _TYPE_HASH =
7 | keccak256(
8 | "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
9 | );
10 |
11 | // Util function
12 | function hashTypedDataV4(
13 | address addr,
14 | bytes32 structHash,
15 | string memory name,
16 | string memory version
17 | ) internal view returns (bytes32) {
18 | bytes32 ds = domainSeparator(name, version, addr);
19 | return keccak256(abi.encodePacked("\x19\x01", ds, structHash));
20 | }
21 |
22 | function domainSeparator(
23 | string memory name,
24 | string memory version,
25 | address addr
26 | ) internal view returns (bytes32) {
27 | return
28 | keccak256(
29 | abi.encode(
30 | _TYPE_HASH,
31 | keccak256(bytes(name)),
32 | keccak256(bytes(version)),
33 | block.chainid,
34 | addr
35 | )
36 | );
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/test/utils/TestLibFixture.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import "forge-std/Vm.sol";
6 | import { RolesAuthority } from "../../src/dependencies/solmate/RolesAuthority.sol";
7 |
8 | import { IProfileNFT } from "../../src/interfaces/IProfileNFT.sol";
9 |
10 | import { Constants } from "../../src/libraries/Constants.sol";
11 | import { DataTypes } from "../../src/libraries/DataTypes.sol";
12 | import { ProfileNFT } from "../../src/core/ProfileNFT.sol";
13 | import { LibDeploy } from "../../script/libraries/LibDeploy.sol";
14 |
15 | import { TestLib712 } from "./TestLib712.sol";
16 | import { PermissionedFeeCreationMw } from "../../src/middlewares/profile/PermissionedFeeCreationMw.sol";
17 |
18 | // Only for testing, not for deploying script
19 | // TODO: move to test folder
20 | library TestLibFixture {
21 | // Need to be called after auth
22 | string private constant avatar = "avatar";
23 | string private constant metadata = "metadata";
24 |
25 | function registerProfile(
26 | Vm vm,
27 | ProfileNFT profile,
28 | PermissionedFeeCreationMw mw,
29 | string memory handle,
30 | address mintToEOA,
31 | uint256 signerPk
32 | ) internal returns (uint256 profileId) {
33 | uint256 deadline = block.timestamp + 60 * 60;
34 | uint256 nonce = mw.getNonce(address(profile), mintToEOA);
35 | address operator = address(0);
36 |
37 | bytes32 digest = TestLib712.hashTypedDataV4(
38 | address(mw),
39 | keccak256(
40 | abi.encode(
41 | Constants._CREATE_PROFILE_TYPEHASH,
42 | mintToEOA,
43 | keccak256(bytes(handle)),
44 | keccak256(bytes(avatar)),
45 | keccak256(bytes(metadata)),
46 | operator,
47 | nonce,
48 | deadline
49 | )
50 | ),
51 | "PermissionedFeeCreationMw",
52 | "1"
53 | );
54 | (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPk, digest);
55 | profileId = profile.createProfile{
56 | value: LibDeploy._INITIAL_FEE_TIER2
57 | }(
58 | DataTypes.CreateProfileParams(
59 | mintToEOA,
60 | handle,
61 | avatar,
62 | metadata,
63 | address(0)
64 | ),
65 | abi.encode(v, r, s, deadline),
66 | new bytes(0)
67 | );
68 | require(mw.getNonce(address(profile), mintToEOA) == nonce + 1);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/test/utils/TestProxy.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0-or-later
2 |
3 | pragma solidity 0.8.14;
4 |
5 | import { BeaconProxy } from "openzeppelin-contracts/contracts/proxy/beacon/BeaconProxy.sol";
6 |
7 | import { ISubscribeNFT } from "../../src/interfaces/ISubscribeNFT.sol";
8 | import { IEssenceNFT } from "../../src/interfaces/IEssenceNFT.sol";
9 | import { LibString } from "../../src/libraries/LibString.sol";
10 | import { Constants } from "../../src/libraries/Constants.sol";
11 |
12 | import { LibDeploy } from "../../script/libraries/LibDeploy.sol";
13 |
14 | contract TestProxy {
15 | function getDeployedSubProxyAddress(
16 | address subscribeBeacon,
17 | uint256 profileId,
18 | address profile,
19 | string memory handle
20 | ) internal pure returns (address) {
21 | string memory name = string(
22 | abi.encodePacked(handle, Constants._SUBSCRIBE_NFT_NAME_SUFFIX)
23 | );
24 | string memory symbol = string(
25 | abi.encodePacked(
26 | LibString.toUpper(handle),
27 | Constants._SUBSCRIBE_NFT_SYMBOL_SUFFIX
28 | )
29 | );
30 | return
31 | LibDeploy._computeAddress(
32 | abi.encodePacked(
33 | type(BeaconProxy).creationCode,
34 | abi.encode(
35 | subscribeBeacon,
36 | abi.encodeWithSelector(
37 | ISubscribeNFT.initialize.selector,
38 | profileId,
39 | name,
40 | symbol
41 | )
42 | )
43 | ),
44 | bytes32(profileId),
45 | profile
46 | );
47 | }
48 |
49 | function getDeployedEssProxyAddress(
50 | address essBeacon,
51 | uint256 profileId,
52 | uint256 essenceId,
53 | address profile,
54 | string memory name,
55 | string memory symbol,
56 | bool transferable
57 | ) internal pure returns (address) {
58 | return
59 | LibDeploy._computeAddress(
60 | abi.encodePacked(
61 | type(BeaconProxy).creationCode,
62 | abi.encode(
63 | essBeacon,
64 | abi.encodeWithSelector(
65 | IEssenceNFT.initialize.selector,
66 | profileId,
67 | essenceId,
68 | name,
69 | symbol,
70 | transferable
71 | )
72 | )
73 | ),
74 | bytes32(profileId),
75 | profile
76 | );
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2020",
4 | "module": "commonjs",
5 | "esModuleInterop": true,
6 | "forceConsistentCasingInFileNames": true,
7 | "strict": true,
8 | "skipLibCheck": true
9 | }
10 | }
11 |
--------------------------------------------------------------------------------