├── tsconfig.json ├── .gitignore ├── lib ├── FeeType.sol ├── external │ ├── ERC2771ContextUpgradeable.sol │ ├── SafeERC20.sol │ └── layer-zero │ │ └── ExcessivelySafeCall.sol └── CurrencyTransferLib.sol ├── interfaces ├── IWETH.sol ├── IERC20TokenUpgradeable.sol ├── external │ ├── layer-zero │ │ ├── ILayerZeroReceiver.sol │ │ ├── ILayerZeroReceiverUpgradeable.sol │ │ ├── ILayerZeroUserApplicationConfigUpgradeable.sol │ │ ├── IONFT721CoreUpgradeable.sol │ │ ├── ILayerZeroEndpoint.sol │ │ └── ILayerZeroEndpointUpgradeable.sol │ └── IERC20.sol └── IPlatformFee.sol ├── contracts ├── factory │ ├── interfaces │ │ └── IFactory.sol │ └── TransparentUpgradeableProxyFactory.sol ├── teva-system │ ├── Session.sol │ ├── SessionAccountFactory.sol │ ├── Multicall.sol │ ├── MultiPurposeFeeCollector.sol │ └── SessionAccount.sol ├── karmapoint │ └── Claim.sol ├── proxy │ └── transparent │ │ ├── ProxyAdmin.sol │ │ └── TransparentUpgradeableProxy.sol ├── dex │ └── libraries │ │ └── DexLibrary.sol ├── external │ └── layer-zero │ │ └── lzApp │ │ └── NonblockingLzAppUpgradeable.sol └── guardians │ ├── ReformistSphinxV2.sol │ ├── GuardianBundlerV1.sol │ ├── ReformistSphinxV1.sol │ ├── crosschain │ ├── NomadicYetiV1.sol │ ├── BalancerDragonV1.sol │ ├── SimplifierKrakenV1.sol │ ├── InnovativeUnicornV1.sol │ └── InfluentialWerewolfV1.sol │ └── GuardianBundlerV2.sol ├── deploy └── zksync │ ├── weth_deploy.ts │ ├── multicall_deploy.ts │ ├── karmapoint │ └── kpv1_deploy.ts │ ├── reformistsphinxv1_deploy.ts │ ├── multitokenpoolammv1_deploy.ts │ ├── marketplace_deploy.ts │ ├── karmapointv1_deploy.ts │ ├── citizenidv1_deploy.ts │ ├── magicalphoenixv1_deploy.ts │ ├── nomadicyetiv1_deploy.ts │ ├── balancerdragonv1_deploy.ts │ ├── simplifierkrakenv1_deploy.ts │ ├── innovativeunicornv1_deploy.ts │ ├── guardianbundlerv1_deploy.ts │ └── influentialwerewolfv1_deploy.ts ├── package.json ├── README.md ├── hardhat.config.ts └── .env.template /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "NodeNext", 4 | "moduleResolution": "NodeNext" 5 | } 6 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | artifacts/ 2 | artifacts-zk/ 3 | cache/ 4 | cache-zk/ 5 | node_modules/ 6 | ABI/ 7 | build/ 8 | .env 9 | .openzeppelin 10 | deployments/ 11 | typechain-types/ 12 | deployments-zk/ 13 | 14 | test-contracts 15 | errors.txt -------------------------------------------------------------------------------- /lib/FeeType.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity ^0.8.18; 3 | 4 | library FeeType { 5 | uint256 internal constant PRIMARY_SALE = 0; 6 | uint256 internal constant MARKET_SALE = 1; 7 | uint256 internal constant SPLIT = 2; 8 | } -------------------------------------------------------------------------------- /interfaces/IWETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity ^0.8.18; 3 | 4 | interface IWETH { 5 | function deposit() external payable; 6 | 7 | function withdraw(uint256 amount) external; 8 | 9 | function transfer(address to, uint256 value) external returns (bool); 10 | } 11 | -------------------------------------------------------------------------------- /interfaces/IERC20TokenUpgradeable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity ^0.8.18; 3 | import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; 4 | 5 | interface IERC20TokenUpgradeable is IERC20Upgradeable { 6 | function mint( 7 | address to, 8 | uint256 amount 9 | ) external; 10 | 11 | function burn( 12 | address from, 13 | uint256 amount 14 | ) external; 15 | 16 | } -------------------------------------------------------------------------------- /contracts/factory/interfaces/IFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.18; 3 | 4 | interface IFactory { 5 | /// @notice Event emitted when a contract is created with the factory 6 | /// @param creator The message sender 7 | /// @param created The created contract 8 | event ContractCreated(address indexed creator, address created); 9 | 10 | /// @notice Creates a new contract 11 | /// @param constructorData The constructor data passed to the new contract 12 | /// @return created The created contract address 13 | function create( 14 | bytes memory constructorData 15 | ) external returns (address created); 16 | } -------------------------------------------------------------------------------- /interfaces/external/layer-zero/ILayerZeroReceiver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | interface ILayerZeroReceiver { 6 | // @notice LayerZero endpoint will invoke this function to deliver the message on the destination 7 | // @param _srcChainId - the source endpoint identifier 8 | // @param _srcAddress - the source sending contract address from the source chain 9 | // @param _nonce - the ordered message nonce 10 | // @param _payload - the signed payload is the UA bytes has encoded to be sent 11 | function lzReceive( 12 | uint16 _srcChainId, 13 | bytes calldata _srcAddress, 14 | uint64 _nonce, 15 | bytes calldata _payload 16 | ) external; 17 | } 18 | -------------------------------------------------------------------------------- /interfaces/external/layer-zero/ILayerZeroReceiverUpgradeable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.2; 4 | 5 | interface ILayerZeroReceiverUpgradeable { 6 | // @notice LayerZero endpoint will invoke this function to deliver the message on the destination 7 | // @param _srcChainId - the source endpoint identifier 8 | // @param _srcAddress - the source sending contract address from the source chain 9 | // @param _nonce - the ordered message nonce 10 | // @param _payload - the signed payload is the UA bytes has encoded to be sent 11 | function lzReceive( 12 | uint16 _srcChainId, 13 | bytes calldata _srcAddress, 14 | uint64 _nonce, 15 | bytes calldata _payload 16 | ) external; 17 | } 18 | -------------------------------------------------------------------------------- /contracts/factory/TransparentUpgradeableProxyFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.18; 3 | 4 | import {TransparentUpgradeableProxy} from "../proxy/transparent/TransparentUpgradeableProxy.sol"; 5 | import {IFactory} from "./interfaces/IFactory.sol"; 6 | 7 | contract TransparentUpgradeableProxyFactory is IFactory { 8 | /// @inheritdoc IFactory 9 | function create( 10 | bytes memory constructorData 11 | ) external override returns (address created) { 12 | (address _logic, address admin_, bytes memory _data) = abi.decode( 13 | constructorData, 14 | (address, address, bytes) 15 | ); 16 | 17 | created = address(new TransparentUpgradeableProxy(_logic, admin_, _data)); 18 | 19 | emit ContractCreated(msg.sender, created); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /interfaces/IPlatformFee.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity ^0.8.18; 3 | 4 | interface IPlatformFee { 5 | /// @dev Returns the platform fee bps and recipient. 6 | function getPlatformFeeInfo() 7 | external 8 | view 9 | returns ( 10 | address, 11 | uint16, 12 | uint16 13 | ); 14 | 15 | /// @dev Lets a module admin update the fees on primary sales. 16 | function setPlatformFeeInfo( 17 | address _platformFeeRecipient, 18 | uint256 _tevanPlatformFeeBps, 19 | uint256 _nonTevanPlatformFeeBps 20 | ) external; 21 | 22 | /// @dev Emitted when fee on primary sales is updated. 23 | event PlatformFeeInfoUpdated( 24 | address indexed platformFeeRecipient, 25 | uint256 tevanPlatformFeeBps, 26 | uint256 nonTevanPlatformFeeBps 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /interfaces/external/IERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.8.0; 3 | 4 | /** 5 | * @title ERC20 interface 6 | * @dev see https://github.com/ethereum/EIPs/issues/20 7 | */ 8 | interface IERC20 { 9 | function totalSupply() external view returns (uint256); 10 | 11 | function balanceOf(address who) external view returns (uint256); 12 | 13 | function allowance(address owner, address spender) external view returns (uint256); 14 | 15 | function transfer(address to, uint256 value) external returns (bool); 16 | 17 | function approve(address spender, uint256 value) external returns (bool); 18 | 19 | function transferFrom( 20 | address from, 21 | address to, 22 | uint256 value 23 | ) external returns (bool); 24 | 25 | event Transfer(address indexed from, address indexed to, uint256 value); 26 | 27 | event Approval(address indexed owner, address indexed spender, uint256 value); 28 | } -------------------------------------------------------------------------------- /contracts/teva-system/Session.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity ^0.8.18; 3 | 4 | import "@openzeppelin/contracts/access/Ownable.sol"; 5 | 6 | contract Session is Ownable { 7 | struct SessionInfo { 8 | uint256 version; 9 | uint256 expirationTime; 10 | bool expired; 11 | } 12 | 13 | mapping(address => SessionInfo) public sessions; 14 | 15 | function createSession( 16 | address authorizedSigner, 17 | uint256 secondsUntilEndTime 18 | ) external onlyOwner { 19 | sessions[authorizedSigner].version += 1; 20 | sessions[authorizedSigner].expirationTime = 21 | block.timestamp + 22 | secondsUntilEndTime; 23 | sessions[authorizedSigner].expired = false; 24 | } 25 | 26 | function deleteSession(address authorizedSigner) external onlyOwner { 27 | sessions[authorizedSigner].expirationTime = block.timestamp; 28 | sessions[authorizedSigner].expired = true; 29 | } 30 | 31 | function inSession(address authorizedSigner) internal view returns (bool) { 32 | if (sessions[authorizedSigner].expired) { 33 | return false; 34 | } 35 | 36 | return true; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /deploy/zksync/weth_deploy.ts: -------------------------------------------------------------------------------- 1 | import { Wallet } from "zksync-ethers"; 2 | import { HardhatRuntimeEnvironment } from "hardhat/types"; 3 | import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; 4 | import * as dotenv from "dotenv"; 5 | 6 | dotenv.config(); 7 | 8 | // An example of a deploy script that will deploy and call a simple contract. 9 | export default async function (hre: HardhatRuntimeEnvironment) { 10 | console.log(`Running deploy script for the WETH contract`); 11 | 12 | // Initialize the wallet. 13 | const wallet = new Wallet(`${process.env.CONTRACT_ADMIN_WALLET_PK}`); 14 | 15 | // Create deployer object and load the artifact of the contract we want to deploy. 16 | const deployer = new Deployer(hre, wallet); 17 | const artifact = await deployer.loadArtifact("WETH"); 18 | 19 | console.log("wallet address: ", await wallet.getAddress()); 20 | 21 | // constructor arguments 22 | const constructorArgs = []; 23 | 24 | const wethContract = await deployer.deploy(artifact, constructorArgs); 25 | console.log("args" + wethContract.interface.encodeDeploy(constructorArgs)); 26 | 27 | // Show the contract info. 28 | const contractAddress = await wethContract.getAddress(); 29 | console.log(`${artifact.contractName} was deployed to ${contractAddress}`); 30 | 31 | // verify the weth contract 32 | console.log("Verifying WETH..."); 33 | await hre.run("verify:verify", { 34 | address: contractAddress, 35 | constructorArguments: constructorArgs, 36 | }); 37 | } 38 | -------------------------------------------------------------------------------- /interfaces/external/layer-zero/ILayerZeroUserApplicationConfigUpgradeable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.2; 4 | 5 | interface ILayerZeroUserApplicationConfigUpgradeable { 6 | // @notice set the configuration of the LayerZero messaging library of the specified version 7 | // @param _version - messaging library version 8 | // @param _chainId - the chainId for the pending config change 9 | // @param _configType - type of configuration. every messaging library has its own convention. 10 | // @param _config - configuration in the bytes. can encode arbitrary content. 11 | function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external; 12 | 13 | // @notice set the send() LayerZero messaging library version to _version 14 | // @param _version - new messaging library version 15 | function setSendVersion(uint16 _version) external; 16 | 17 | // @notice set the lzReceive() LayerZero messaging library version to _version 18 | // @param _version - new messaging library version 19 | function setReceiveVersion(uint16 _version) external; 20 | 21 | // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload 22 | // @param _srcChainId - the chainId of the source chain 23 | // @param _srcAddress - the contract address of the source contract at the source chain 24 | function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external; 25 | } -------------------------------------------------------------------------------- /deploy/zksync/multicall_deploy.ts: -------------------------------------------------------------------------------- 1 | import { Wallet } from "zksync-ethers"; 2 | import { HardhatRuntimeEnvironment } from "hardhat/types"; 3 | import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; 4 | import * as dotenv from "dotenv"; 5 | 6 | dotenv.config(); 7 | 8 | // An example of a deploy script that will deploy and call a simple contract. 9 | export default async function (hre: HardhatRuntimeEnvironment) { 10 | console.log(`Running deploy script for the Multicall contract`); 11 | 12 | // Initialize the wallet. 13 | const wallet = new Wallet(`${process.env.CONTRACT_ADMIN_WALLET_PK}`); 14 | 15 | // Create deployer object and load the artifact of the contract we want to deploy. 16 | const deployer = new Deployer(hre, wallet); 17 | const artifact = await deployer.loadArtifact("Multicall"); 18 | 19 | console.log("wallet address: ", await wallet.getAddress()); 20 | 21 | // constructor arguments 22 | const constructorArgs = []; 23 | 24 | const multicallContract = await deployer.deploy(artifact, constructorArgs); 25 | console.log( 26 | "args" + multicallContract.interface.encodeDeploy(constructorArgs) 27 | ); 28 | 29 | // Show the contract info. 30 | const contractAddress = await multicallContract.getAddress(); 31 | console.log(`${artifact.contractName} was deployed to ${contractAddress}`); 32 | 33 | // verify the multicall contract 34 | console.log("Verifying Multicall..."); 35 | await hre.run("verify:verify", { 36 | address: contractAddress, 37 | constructorArguments: constructorArgs 38 | }); 39 | } 40 | -------------------------------------------------------------------------------- /contracts/teva-system/SessionAccountFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity ^0.8.18; 3 | 4 | import "@matterlabs/zksync-contracts/l2/system-contracts/Constants.sol"; 5 | import "@matterlabs/zksync-contracts/l2/system-contracts/libraries/SystemContractsCaller.sol"; 6 | 7 | contract SessionAccountFactory { 8 | bytes32 public aaBytecodeHash; 9 | 10 | constructor(bytes32 _aaBytecodeHash) { 11 | aaBytecodeHash = _aaBytecodeHash; 12 | } 13 | 14 | event SessionAccountCreated(address indexed owner, address indexed accountAddress); 15 | 16 | function deployAccount( 17 | bytes32 salt, 18 | address owner 19 | ) external returns (address accountAddress) { 20 | (bool success, bytes memory returnData) = SystemContractsCaller 21 | .systemCallWithReturndata( 22 | uint32(gasleft()), 23 | address(DEPLOYER_SYSTEM_CONTRACT), 24 | uint128(0), 25 | abi.encodeCall( 26 | DEPLOYER_SYSTEM_CONTRACT.create2Account, 27 | ( 28 | salt, 29 | aaBytecodeHash, 30 | abi.encode(owner), 31 | IContractDeployer.AccountAbstractionVersion.Version1 32 | ) 33 | ) 34 | ); 35 | require(success, "Deployment failed"); 36 | 37 | (accountAddress) = abi.decode(returnData, (address)); 38 | 39 | // emit the event with owner address and newly created session wallet address 40 | emit SessionAccountCreated(owner, accountAddress); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tevaeralabs-contracts", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "devDependencies": { 7 | "@matterlabs/hardhat-zksync-deploy": "^1.2.0", 8 | "@matterlabs/hardhat-zksync-solc": "^1.1.4", 9 | "@matterlabs/hardhat-zksync-upgradable": "^1.3.0", 10 | "@matterlabs/hardhat-zksync-verify": "^1.4.1", 11 | "@matterlabs/zksync-contracts": "^0.6.1", 12 | "@nomicfoundation/hardhat-chai-matchers": "^2.0.6", 13 | "@nomicfoundation/hardhat-ethers": "^3.0.5", 14 | "@nomicfoundation/hardhat-network-helpers": "^1.0.10", 15 | "@nomicfoundation/hardhat-toolbox": "^4.0.0", 16 | "@nomicfoundation/hardhat-verify": "^2.0.4", 17 | "@nomiclabs/hardhat-etherscan": "^3.1.7", 18 | "@openzeppelin/contracts": "^4.9.6", 19 | "@openzeppelin/contracts-upgradeable": "^4.9.6", 20 | "@openzeppelin/hardhat-upgrades": "^3.0.4", 21 | "@typechain/ethers-v6": "^0.5.1", 22 | "@typechain/hardhat": "^9.1.0", 23 | "@types/chai": "^4.3.12", 24 | "@types/mocha": "^10.0.6", 25 | "@types/node": "^20.11.24", 26 | "chai": "^4.2.0", 27 | "dotenv": "^16.4.5", 28 | "hardhat": "^2.22.4", 29 | "ethers": "^6.11.1", 30 | "hardhat-gas-reporter": "^1.0.10", 31 | "mocha": "^10.3.0", 32 | "sol-merger": "^4.4.1", 33 | "solidity-coverage": "^0.8.10", 34 | "ts-node": "^10.9.2", 35 | "typechain": "^8.3.2", 36 | "typescript": "^5.3.3", 37 | "zksync-ethers": "^6.4.0" 38 | }, 39 | "scripts": { 40 | "test": "set NODE_ENV=test && hardhat test", 41 | "build-contracts": "sol-merger \"./contracts/*.sol\" ./build" 42 | }, 43 | "resolutions": { 44 | "strip-ansi": "6.0.0" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tevaera Smart Contracts 2 | Tevaera Contracts on ZKsync 3 | 4 | The repo consists of tevaera core contracts 5 | 6 | ### Project Setup 7 | 8 | 1. Once you clone the repo, run in terminal 9 | > yarn install 10 | 11 | 2. Clone https://github.com/matter-labs/local-setup repo separately to run zksync image in Docker. Follow the steps as mentioned in the repo to successfully start a ZKsync instant on your local machine 12 | 13 | ***Make sure to start the ZKsync local-setup via WSL 2 before starting with the below steps. 14 | 15 | ### Compiling the Contracts 16 | 17 | To compile all the contracts, run in terminal: - 18 | > yarn hardhat compile --network 19 | 20 | ### Deploy contracts on ZKsync 21 | 22 | To deploy the separate contracts, run in terminal: - 23 | > yarn hardhat deploy-zksync --script --network 24 | 25 | Ex: yarn hardhat deploy-zksync --script zksync/citizenidv1_deploy.ts --network zksyncSepolia 26 | 27 | ### Deploy contracts on other chains 28 | 29 | To deploy the separate contracts, run in terminal: - 30 | > yarn hardhat run --network 31 | 32 | Ex: yarn hardhat run deploy/arbitrum/balancerdragonv1_deploy.ts --network arbitrumSepolia 33 | 34 | ### Testing contracts 35 | 36 | To test the CitizenId contract, run in terminal: - 37 | > yarn hardhat test test/cz.id.test.ts 38 | 39 | To test the Karma Points contract, run in terminal: - 40 | > yarn hardhat test test/kp.test.ts 41 | 42 | ### Flatten the contracts 43 | 44 | > npx hardhat flatten ./contracts/ >> ./Flatten/ 45 | 46 | ### Verifying the contracts 47 | 48 | https://code.zksync.io/tutorials/how-to-verify-contracts 49 | 50 | ### ZkSync Regenesis 51 | 52 | Get ETH in wallet via ZKsync Bridge or Faucet -> https://portal.zksync.io/ 53 | Delete cache-zk and artifacts-zk 54 | Then, compile and re-deploy the contracts 55 | 56 | To get more info about using Hardhat with ZKsync, visit https://docs.zksync.io/build/tooling/hardhat/guides/getting-started 57 | To get tokens for testing on ZKsync, visit https://portal.zksync.io 58 | -------------------------------------------------------------------------------- /contracts/karmapoint/Claim.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.18; 3 | 4 | import "../citizenid/CitizenIDV1.sol"; 5 | import "./KarmaPointV1.sol"; 6 | import "@openzeppelin/contracts/access/Ownable.sol"; 7 | import "@openzeppelin/contracts/security/Pausable.sol"; 8 | 9 | /// @title Airdrop claim contract for Citizen ID & Karma Points 10 | /// @author Tevaera Labs 11 | /// @notice Claims airdropped Citizen ID & Karma Points 12 | /// @dev Uses CitizenID and KarmaPoint contracts for minting 13 | contract Claim is Ownable, Pausable { 14 | CitizenIDV1 internal citizenIdContract; 15 | KarmaPointV1 internal kpContract; 16 | 17 | modifier isNotBlacklisted() { 18 | require( 19 | !citizenIdContract.blacklisted(msg.sender), 20 | "Tevan Blacklisted!" 21 | ); 22 | _; 23 | } 24 | 25 | constructor(CitizenIDV1 _citizenIdContract, KarmaPointV1 _kpContract) { 26 | citizenIdContract = _citizenIdContract; 27 | kpContract = _kpContract; 28 | } 29 | 30 | /// @notice Users gets citizen id and karma points if eligible 31 | /// @dev Mints citizen id and karma points 32 | function claim() external payable isNotBlacklisted whenNotPaused { 33 | if (citizenIdContract.balanceOf(msg.sender) == 0) { 34 | citizenIdContract.claim{value: msg.value}(msg.sender); 35 | } else { 36 | require(msg.value == 0, "unexpected ether sent"); 37 | } 38 | 39 | if (kpContract.toBeClaimedKP(msg.sender) > 0) { 40 | kpContract.claim(msg.sender); 41 | } 42 | } 43 | 44 | /// @dev Owner can update the citizen id contract address 45 | function setCitizenIdContract( 46 | CitizenIDV1 _newCitizenIdContract 47 | ) external onlyOwner { 48 | citizenIdContract = _newCitizenIdContract; 49 | } 50 | 51 | /// @dev Owner can update the KP contract address 52 | function setKpContract(KarmaPointV1 _newKpContract) external onlyOwner { 53 | kpContract = _newKpContract; 54 | } 55 | 56 | /// @dev Owner can pause the claim 57 | function pause() external onlyOwner whenNotPaused { 58 | _pause(); 59 | } 60 | 61 | /// @dev Owner can activate the claim 62 | function unpause() external onlyOwner whenPaused { 63 | _unpause(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /lib/external/ERC2771ContextUpgradeable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // OpenZeppelin Contracts v4.4.0 (metatx/ERC2771Context.sol) 3 | 4 | pragma solidity ^0.8.11; 5 | 6 | import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; 7 | import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; 8 | 9 | /** 10 | * @dev Context variant with ERC2771 support. 11 | */ 12 | abstract contract ERC2771ContextUpgradeable is 13 | Initializable, 14 | ContextUpgradeable 15 | { 16 | mapping(address => bool) private _trustedForwarder; 17 | 18 | function __ERC2771Context_init( 19 | address[] memory trustedForwarder 20 | ) internal onlyInitializing { 21 | __Context_init_unchained(); 22 | __ERC2771Context_init_unchained(trustedForwarder); 23 | } 24 | 25 | function __ERC2771Context_init_unchained( 26 | address[] memory trustedForwarder 27 | ) internal onlyInitializing { 28 | for (uint256 i = 0; i < trustedForwarder.length; i++) { 29 | _trustedForwarder[trustedForwarder[i]] = true; 30 | } 31 | } 32 | 33 | function isTrustedForwarder( 34 | address forwarder 35 | ) public view virtual returns (bool) { 36 | return _trustedForwarder[forwarder]; 37 | } 38 | 39 | function _msgSender() internal view virtual override returns (address) { 40 | uint256 calldataLength = msg.data.length; 41 | uint256 contextSuffixLength = _contextSuffixLength(); 42 | if ( 43 | isTrustedForwarder(msg.sender) && 44 | calldataLength >= contextSuffixLength 45 | ) { 46 | return 47 | address( 48 | bytes20(msg.data[calldataLength - contextSuffixLength:]) 49 | ); 50 | } else { 51 | return super._msgSender(); 52 | } 53 | } 54 | 55 | function _msgData() 56 | internal 57 | view 58 | virtual 59 | override 60 | returns (bytes calldata) 61 | { 62 | uint256 calldataLength = msg.data.length; 63 | uint256 contextSuffixLength = _contextSuffixLength(); 64 | if ( 65 | isTrustedForwarder(msg.sender) && 66 | calldataLength >= contextSuffixLength 67 | ) { 68 | return msg.data[:calldataLength - contextSuffixLength]; 69 | } else { 70 | return super._msgData(); 71 | } 72 | } 73 | 74 | /** 75 | * @dev ERC-2771 specifies the context as being a single address (20 bytes). 76 | */ 77 | function _contextSuffixLength() 78 | internal 79 | view 80 | virtual 81 | override 82 | returns (uint256) 83 | { 84 | return 20; 85 | } 86 | 87 | uint256[49] private __gap; 88 | } 89 | -------------------------------------------------------------------------------- /hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import "@matterlabs/hardhat-zksync-deploy"; 2 | import "@matterlabs/hardhat-zksync-solc"; 3 | import "@matterlabs/hardhat-zksync-verify"; 4 | import "@matterlabs/hardhat-zksync-upgradable"; 5 | import "@nomicfoundation/hardhat-toolbox"; 6 | 7 | const config = { 8 | solidity: { 9 | version: "0.8.18", 10 | settings: { 11 | optimizer: { 12 | enabled: true, 13 | runs: 200, 14 | }, 15 | viaIR: true, 16 | }, 17 | }, 18 | zksolc: { 19 | version: "1.4.1", 20 | compilerSource: "binary", 21 | settings: {}, 22 | }, 23 | defaultNetwork: "zkSyncSepolia", 24 | 25 | networks: { 26 | hardhat: { 27 | zksync: true, 28 | }, 29 | zkSyncLocal: { 30 | url: "http://localhost:8011", 31 | ethNetwork: "http://localhost:8545", 32 | zksync: true, 33 | }, 34 | zkSyncGoerli: { 35 | url: "https://testnet.era.zksync.dev", 36 | ethNetwork: "goerli", 37 | zksync: true, 38 | verifyURL: 39 | "https://zksync2-testnet-explorer.zksync.dev/contract_verification", 40 | }, 41 | zkSyncSepolia: { 42 | url: "https://sepolia.era.zksync.dev", 43 | ethNetwork: "sepolia", 44 | zksync: true, 45 | verifyURL: 46 | "https://explorer.sepolia.era.zksync.dev/contract_verification", 47 | }, 48 | zkSyncMainnet: { 49 | url: "https://mainnet.era.zksync.io", 50 | ethNetwork: "mainnet", 51 | zksync: true, 52 | verifyURL: 53 | "https://zksync2-mainnet-explorer.zksync.io/contract_verification", 54 | }, 55 | arbitrumGoerli: { 56 | url: "https://goerli-rollup.arbitrum.io/rpc", 57 | zksync: false, 58 | }, 59 | arbitrumSepolia: { 60 | url: "https://sepolia-rollup.arbitrum.io/rpc", 61 | zksync: false, 62 | }, 63 | arbitrumOne: { 64 | url: "https://arb1.arbitrum.io/rpc", 65 | zksync: false, 66 | }, 67 | lineaGoerli: { 68 | url: "https://rpc.goerli.linea.build", 69 | zksync: false, 70 | }, 71 | baseGoerli: { 72 | url: "https://goerli.base.org", 73 | zksync: false, 74 | }, 75 | baseSepolia: { 76 | url: "https://sepolia.base.org", 77 | zksync: false, 78 | }, 79 | scrollSepolia: { 80 | url: "https://sepolia-rpc.scroll.io", 81 | zksync: false, 82 | }, 83 | }, 84 | etherscan: { 85 | apiKey: { 86 | arbitrumGoerli: "KY7VQ8AYNP5C29DJUYGDIPBFC5VD13JS3D", 87 | linea_testnet: "GX5C89P3SWF2CK9EXQBAD2KW9WGBRQNX53", 88 | }, 89 | customChains: [ 90 | { 91 | network: "linea_testnet", 92 | chainId: 59140, 93 | urls: { 94 | apiURL: "https://api-testnet.lineascan.build/api", 95 | browserURL: "https://goerli.lineascan.build/address", 96 | }, 97 | }, 98 | ], 99 | }, 100 | }; 101 | 102 | export default config; 103 | -------------------------------------------------------------------------------- /contracts/proxy/transparent/ProxyAdmin.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol) 3 | 4 | pragma solidity 0.8.18; 5 | 6 | import "@openzeppelin/contracts/access/Ownable.sol"; 7 | import "./TransparentUpgradeableProxy.sol"; 8 | 9 | /** 10 | * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an 11 | * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}. 12 | */ 13 | contract ProxyAdmin is Ownable { 14 | /** 15 | * @dev Returns the current implementation of `proxy`. 16 | * 17 | * Requirements: 18 | * 19 | * - This contract must be the admin of `proxy`. 20 | */ 21 | function getProxyImplementation( 22 | TransparentUpgradeableProxy proxy 23 | ) public view virtual returns (address) { 24 | // We need to manually run the static call since the getter cannot be flagged as view 25 | // bytes4(keccak256("implementation()")) == 0x5c60da1b 26 | (bool success, bytes memory returndata) = address(proxy).staticcall( 27 | hex"5c60da1b" 28 | ); 29 | require(success); 30 | return abi.decode(returndata, (address)); 31 | } 32 | 33 | /** 34 | * @dev Returns the current admin of `proxy`. 35 | * 36 | * Requirements: 37 | * 38 | * - This contract must be the admin of `proxy`. 39 | */ 40 | function getProxyAdmin( 41 | TransparentUpgradeableProxy proxy 42 | ) public view virtual returns (address) { 43 | // We need to manually run the static call since the getter cannot be flagged as view 44 | // bytes4(keccak256("admin()")) == 0xf851a440 45 | (bool success, bytes memory returndata) = address(proxy).staticcall( 46 | hex"f851a440" 47 | ); 48 | require(success); 49 | return abi.decode(returndata, (address)); 50 | } 51 | 52 | /** 53 | * @dev Changes the admin of `proxy` to `newAdmin`. 54 | * 55 | * Requirements: 56 | * 57 | * - This contract must be the current admin of `proxy`. 58 | */ 59 | function changeProxyAdmin( 60 | TransparentUpgradeableProxy proxy, 61 | address newAdmin 62 | ) public virtual onlyOwner { 63 | proxy.changeAdmin(newAdmin); 64 | } 65 | 66 | /** 67 | * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. 68 | * 69 | * Requirements: 70 | * 71 | * - This contract must be the admin of `proxy`. 72 | */ 73 | function upgrade( 74 | TransparentUpgradeableProxy proxy, 75 | address implementation 76 | ) public virtual onlyOwner { 77 | proxy.upgradeTo(implementation); 78 | } 79 | 80 | /** 81 | * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See 82 | * {TransparentUpgradeableProxy-upgradeToAndCall}. 83 | * 84 | * Requirements: 85 | * 86 | * - This contract must be the admin of `proxy`. 87 | */ 88 | function upgradeAndCall( 89 | TransparentUpgradeableProxy proxy, 90 | address implementation, 91 | bytes memory data 92 | ) public payable virtual onlyOwner { 93 | proxy.upgradeToAndCall{value: msg.value}(implementation, data); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /contracts/teva-system/Multicall.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity ^0.8.18; 3 | 4 | /** 5 | * @title Multicall 6 | * @dev Contract that aggregates multiple contract function calls into a single call. 7 | */ 8 | contract Multicall { 9 | // Event emitted when calls are aggregated 10 | event AggregatedCalls(uint256 count); 11 | 12 | /** 13 | * @notice Aggregate non-payable multiple calls into a single call. 14 | * @param targets The addresses of the contracts to call. 15 | * @param callDatas The function call data for the corresponding contracts. 16 | * @return returnDatas The return data for each call. 17 | */ 18 | function aggregate( 19 | address[] calldata targets, 20 | bytes[] calldata callDatas 21 | ) external returns (bytes[] memory returnDatas) { 22 | // Ensure the input arrays match in length. 23 | require(targets.length == callDatas.length, "Mismatched input arrays"); 24 | 25 | // Initialize the return data array. 26 | returnDatas = new bytes[](targets.length); 27 | 28 | // Loop through each target address and call data, executing the calls. 29 | for (uint i = 0; i < targets.length; i++) { 30 | (bool success, bytes memory result) = targets[i].call(callDatas[i]); 31 | 32 | // If any of the calls fails, revert the entire transaction. 33 | if (!success) { 34 | // Decode the standard Error(string) response for better error handling 35 | string memory errorMessage; 36 | if (result.length > 0) { 37 | errorMessage = abi.decode(result, (string)); 38 | } else { 39 | errorMessage = "Call failed without a revert message"; 40 | } 41 | revert(errorMessage); 42 | } 43 | 44 | returnDatas[i] = result; 45 | } 46 | 47 | emit AggregatedCalls(targets.length); 48 | } 49 | 50 | /** 51 | * @notice Aggregate payable multiple calls into a single call. 52 | * @param targets The addresses of the contracts to call. 53 | * @param callDatas The function call data for the corresponding contracts. 54 | * @param callDatas The values for the corresponding call datas. 55 | * @return returnDatas The return data for each call. 56 | */ 57 | function aggregatePayable( 58 | address[] calldata targets, 59 | bytes[] calldata callDatas, 60 | uint256[] calldata values 61 | ) external payable returns (bytes[] memory returnDatas) { 62 | require( 63 | targets.length == callDatas.length && 64 | targets.length == values.length, 65 | "Mismatched input arrays" 66 | ); 67 | 68 | returnDatas = new bytes[](targets.length); 69 | 70 | for (uint i = 0; i < targets.length; i++) { 71 | (bool success, bytes memory result) = targets[i].call{ 72 | value: values[i] 73 | }(callDatas[i]); 74 | 75 | // If any of the calls fails, revert the entire transaction. 76 | if (!success) { 77 | // Decode the standard Error(string) response for better error handling 78 | string memory errorMessage; 79 | if (result.length > 0) { 80 | errorMessage = abi.decode(result, (string)); 81 | } else { 82 | errorMessage = "Call failed without a revert message"; 83 | } 84 | revert(errorMessage); 85 | } 86 | 87 | returnDatas[i] = result; 88 | } 89 | 90 | // Ensure no leftover Ether remains in this contract. 91 | uint256 remainingValue = address(this).balance; 92 | if (remainingValue > 0) { 93 | payable(msg.sender).transfer(remainingValue); 94 | } 95 | 96 | emit AggregatedCalls(targets.length); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /lib/CurrencyTransferLib.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity ^0.8.18; 3 | 4 | // Helper interfaces 5 | import {IWETH} from "../interfaces/IWETH.sol"; 6 | 7 | import "./external/SafeERC20.sol"; 8 | 9 | library CurrencyTransferLib { 10 | using SafeERC20 for IERC20; 11 | 12 | /// @dev The address interpreted as native token of the chain. 13 | address public constant NATIVE_TOKEN = 14 | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; 15 | 16 | /// @dev Transfers a given amount of currency. 17 | function transferCurrency( 18 | address _currency, 19 | address _from, 20 | address _to, 21 | uint256 _amount 22 | ) internal { 23 | if (_amount == 0) { 24 | return; 25 | } 26 | 27 | if (_currency == NATIVE_TOKEN) { 28 | safeTransferNativeToken(_to, _amount); 29 | } else { 30 | safeTransferERC20(_currency, _from, _to, _amount); 31 | } 32 | } 33 | 34 | /// @dev Transfers a given amount of currency. (With native token wrapping) 35 | function transferCurrencyWithWrapper( 36 | address _currency, 37 | address _from, 38 | address _to, 39 | uint256 _amount, 40 | address _nativeTokenWrapper 41 | ) internal { 42 | if (_amount == 0) { 43 | return; 44 | } 45 | 46 | if (_currency == NATIVE_TOKEN) { 47 | if (_from == address(this)) { 48 | // withdraw from weth then transfer withdrawn native token to recipient 49 | IWETH(_nativeTokenWrapper).withdraw(_amount); 50 | safeTransferNativeTokenWithWrapper( 51 | _to, 52 | _amount, 53 | _nativeTokenWrapper 54 | ); 55 | } else if (_to == address(this)) { 56 | // store native currency in weth 57 | require(msg.value >=_amount, "msg.value != amount"); 58 | IWETH(_nativeTokenWrapper).deposit{value: _amount}(); 59 | } else { 60 | safeTransferNativeTokenWithWrapper( 61 | _to, 62 | _amount, 63 | _nativeTokenWrapper 64 | ); 65 | } 66 | } else { 67 | safeTransferERC20(_currency, _from, _to, _amount); 68 | } 69 | } 70 | 71 | /// @dev Transfer `amount` of ERC20 token from `from` to `to`. 72 | function safeTransferERC20( 73 | address _currency, 74 | address _from, 75 | address _to, 76 | uint256 _amount 77 | ) internal { 78 | if (_from == _to) { 79 | return; 80 | } 81 | 82 | if (_from == address(this)) { 83 | IERC20(_currency).safeTransfer(_to, _amount); 84 | } else { 85 | IERC20(_currency).safeTransferFrom(_from, _to, _amount); 86 | } 87 | } 88 | 89 | /// @dev Transfers `amount` of native token to `to`. 90 | function safeTransferNativeToken(address to, uint256 value) internal { 91 | // solhint-disable avoid-low-level-calls 92 | // slither-disable-next-line low-level-calls 93 | (bool success, ) = to.call{value: value}(""); 94 | require(success, "native token transfer failed"); 95 | } 96 | 97 | /// @dev Transfers `amount` of native token to `to`. (With native token wrapping) 98 | function safeTransferNativeTokenWithWrapper( 99 | address to, 100 | uint256 value, 101 | address _nativeTokenWrapper 102 | ) internal { 103 | // solhint-disable avoid-low-level-calls 104 | // slither-disable-next-line low-level-calls 105 | (bool success, ) = to.call{value: value, gas: 20000}(""); 106 | if (!success) { 107 | IWETH(_nativeTokenWrapper).deposit{value: value}(); 108 | IERC20(_nativeTokenWrapper).safeTransfer(to, value); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /.env.template: -------------------------------------------------------------------------------- 1 | PROXY_ADMIN_WALLET_PK= 2 | CONTRACT_ADMIN_WALLET_PK= 3 | SAFE_ADDRESS= 4 | CHARITY_ADDRESS= 5 | REP_ADMIN_ADDRESS= 6 | ZKSYNC_PROVIDER_URI= 7 | # 8 | CITIZEN_ID_PRICE= # in ETH (0.0003) 9 | KP_PRICE= # in ETH (0.00003) 10 | KP_TOTAL_SUPPLY_CAP= 11 | KP_BUY_CAP= 12 | CROSSCHAIN_TRANSFER_FEE= # in ETH (0.00006) 13 | MIN_GAS_TO_TRANSFER_AND_STORE= # in ETH (0.000000000000000001) 14 | SINGLE_GUARDIAN_PRICE= # in ETH (0.0003) 15 | BUNDLE_GUARDIAN_PRICE= # in ETH (0.0009) 16 | TEVAN_PLATFORMFEE_BPS= 17 | NONTEVAN_PLATFORMFEE_BPS= 18 | # 19 | CITIZEN_ID_IPFS_IMAGE_URI= 20 | CITIZEN_ID_IPFS_BASE_URI= 21 | REFORMIST_SPHINX_IPFS_IMAGE_URI= 22 | SPHINX_IPFS_BASE_URI= 23 | MAGICAL_PHOENIX_IPFS_BASE_URI= 24 | MAGICAL_PHOENIX_IPFS_CONTRACT_URI= 25 | MARKETPLACE_CONTRACT_IPFS_URL= 26 | BALANCER_DRAGON_IPFS_BASE_URI= 27 | BALANCER_DRAGON_IPFS_CONTRACT_URI= 28 | INNOVATIVE_UNICORN_IPFS_BASE_URI= 29 | INNOVATIVE_UNICORN_IPFS_CONTRACT_URI= 30 | INFLUENTIAL_WEREWOLF_IPFS_BASE_URI= 31 | INFLUENTIAL_WEREWOLF_IPFS_CONTRACT_URI= 32 | NOMADIC_YETI_IPFS_BASE_URI= 33 | NOMADIC_YETI_IPFS_CONTRACT_URI= 34 | SIMPLIFIER_KRAKEN_IPFS_BASE_URI= 35 | SIMPLIFIER_KRAKEN_IPFS_CONTRACT_URI= 36 | # 37 | PROXY_ADMIN_CONTRACT_ADDRESS= 38 | WETH_ADDRESS= 39 | USDC_ADDRESS= 40 | WBTC_ADDRESS= 41 | LAYERZERO_ZKSYNC_ENDPOINT= 42 | LAYERZERO_LINEA_ENDPOINT= 43 | LAYERZERO_ARBITRUM_ENDPOINT= 44 | # 45 | # 46 | # 47 | CITIZEN_ID_CONTRACT_ADDRESS= 48 | KP_CONTRACT_ADDRESS= 49 | CLAIM_CONTRACT_ADDRESS= 50 | REFORMIST_SPHINX_CONTRACT_ADDRESS= 51 | MAGICAL_PHOENIX_CONTRACT_ADDRESS= 52 | MARKETPLACE_CONTRACT_ADDRESS= 53 | # 54 | GUARDIAN_BUNDLER_CONTRACT_ADDRESS= 55 | # 56 | ZKSYNC_BALANCER_DRAGON_CONTRACT_ADDRESS= 57 | ZKSYNC_INFLUENTIAL_WEREWOLF_CONTRACT_ADDRESS= 58 | ZKSYNC_INNOVATIVE_UNICORN_CONTRACT_ADDRESS= 59 | ZKSYNC_NOMADIC_YETI_CONTRACT_ADDRESS= 60 | ZKSYNC_SIMPLIFIER_KRAKEN_CONTRACT_ADDRESS= 61 | # 62 | ARBITRUM_BALANCER_DRAGON_CONTRACT_ADDRESS= 63 | ARBITRUM_INFLUENTIAL_WEREWOLF_CONTRACT_ADDRESS= 64 | ARBITRUM_INNOVATIVE_UNICORN_CONTRACT_ADDRESS= 65 | ARBITRUM_NOMADIC_YETI_CONTRACT_ADDRESS= 66 | ARBITRUM_SIMPLIFIER_KRAKEN_CONTRACT_ADDRESS= 67 | # 68 | LINEA_BALANCER_DRAGON_CONTRACT_ADDRESS= 69 | LINEA_INFLUENTIAL_WEREWOLF_CONTRACT_ADDRESS= 70 | LINEA_INNOVATIVE_UNICORN_CONTRACT_ADDRESS= 71 | LINEA_NOMADIC_YETI_CONTRACT_ADDRESS= 72 | LINEA_SIMPLIFIER_KRAKEN_CONTRACT_ADDRESS= 73 | # 74 | BASE_BALANCER_DRAGON_CONTRACT_ADDRESS= 75 | BASE_INFLUENTIAL_WEREWOLF_CONTRACT_ADDRESS= 76 | BASE_INNOVATIVE_UNICORN_CONTRACT_ADDRESS= 77 | BASE_NOMADIC_YETI_CONTRACT_ADDRESS= 78 | BASE_SIMPLIFIER_KRAKEN_CONTRACT_ADDRESS= 79 | # 80 | SCROLL_BALANCER_DRAGON_CONTRACT_ADDRESS= 81 | SCROLL_INFLUENTIAL_WEREWOLF_CONTRACT_ADDRESS= 82 | SCROLL_INNOVATIVE_UNICORN_CONTRACT_ADDRESS= 83 | SCROLL_NOMADIC_YETI_CONTRACT_ADDRESS= 84 | SCROLL_SIMPLIFIER_KRAKEN_CONTRACT_ADDRESS= 85 | # 86 | ZKSYNC_MULTICALL_CONTRACT_ADDRESS= 87 | SESSION_ACCOUNT_FACTORY_ADDRESS= 88 | # 89 | TEVA_QUEST_REGISTRY_CONTRACT_ADDRESS= 90 | ZEEK_BADGE_CONTRACT_ADDRESS= 91 | # 92 | TEVA_GUARD_IPFS_BASE_URI= 93 | TEVA_GUARD_IPFS_CONTRACT_URI= 94 | TEVA_GUARD_PHASE1_WHITELISTED_DISC_BPS= 95 | TEVA_GUARD_PHASE1_TEVAN_DISC_BPS= 96 | TEVA_GUARD_PHASE1_END_TIME= 97 | TEVA_GUARD_PUBLIC_SALE_END_TIME= 98 | TEVA_GUARD_CONTRACT_ADDRESS= 99 | 100 | # wild whispers 101 | KILL_PROOF_VRIFIER_CONTRACT_ADDRESS= 102 | GUARDIAN_ACTION_VERIFIER_CONTRACT_ADDRESS= 103 | USER_REGISTRY_CONTRACT_ADDRESS= 104 | TASK_REGISTRY_CONTRACT_ADDRESS= 105 | MATCH_REGISTRY_CONTRACT_ADDRESS= 106 | GAME_EVENT_VERIFIER_CONTRACT_ADDRESS= 107 | WW_TRUSTED_CALLERS= 108 | # task registry ipfs base url 109 | TASK_BASE_URL= 110 | 111 | #Dex 112 | DEX_UUPS_PROXY_CONTRACT= 113 | DEX_FEE_TOKEN= 114 | KP_TOKEN_CONTRACT= 115 | TRUSTED_CALLER= 116 | TEVA_TOKEN_CONTRACT= 117 | 118 | # grant role KP script and TGE 119 | DEX_CONTRACT_ADDRESS= 120 | KP_INITIAL_TOKEN_MINT_AMOUNT= 121 | TEVA_INITIAL_TOKEN_MINT_AMOUNT= 122 | 123 | 124 | # Merkel Distributor 125 | MERKEL_ROOT= 126 | MAX_CLAIMABLE_LIMIT= 127 | CLAIM_START_TIME= 128 | CLAIM_END_TIME= 129 | -------------------------------------------------------------------------------- /deploy/zksync/karmapoint/kpv1_deploy.ts: -------------------------------------------------------------------------------- 1 | import { Contract, ContractFactory, Provider, Wallet } from "zksync-ethers"; 2 | import { HardhatRuntimeEnvironment } from "hardhat/types"; 3 | import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; 4 | import * as dotenv from "dotenv"; 5 | 6 | dotenv.config(); 7 | const TransparentUpgradeableProxy = require("../../../artifacts-zk/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json"); 8 | 9 | // An example of a deploy script that will deploy and call a simple contract. 10 | export default async function (hre: HardhatRuntimeEnvironment) { 11 | console.log( 12 | `Running deploy script for the upgradable KPV1 contract with transparent proxy...` 13 | ); 14 | 15 | // environment variables 16 | const provider = new Provider(process.env.ZKSYNC_PROVIDER_URI); 17 | if (!provider) throw new Error("Please set zksync provider url"); 18 | const proxyAdminContractAddress = process.env.PROXY_ADMIN_CONTRACT_ADDRESS; 19 | if (!proxyAdminContractAddress) 20 | throw new Error("Please set proxyAdminContractAddress"); 21 | 22 | // Initialize the safeWallet. 23 | const proxyAdminWallet = new Wallet( 24 | `${process.env.PROXY_ADMIN_WALLET_PK}`, 25 | provider 26 | ); 27 | console.log( 28 | "proxyAdminWallet address: ", 29 | await proxyAdminWallet.getAddress() 30 | ); 31 | 32 | const contractAdminWallet = new Wallet( 33 | `${process.env.CONTRACT_ADMIN_WALLET_PK}`, 34 | provider 35 | ); 36 | console.log( 37 | "contractAdminWallet address: ", 38 | await contractAdminWallet.getAddress() 39 | ); 40 | 41 | // Initialize deployers 42 | const contractDeployer = new Deployer(hre, contractAdminWallet); 43 | 44 | // Deploy the karma point contract 45 | const kpArtifact = await contractDeployer.loadArtifact( 46 | "contracts/karmapoint/KPV1.sol:KarmaPointV1" 47 | ); 48 | const kpConstArgs = []; 49 | const kpContract = await contractDeployer.deploy(kpArtifact, kpConstArgs); 50 | console.log("args: " + kpContract.interface.encodeDeploy(kpConstArgs)); 51 | console.log( 52 | `${ 53 | kpArtifact.contractName 54 | } was deployed to ${await kpContract.getAddress()}` 55 | ); 56 | 57 | const verifyImpl = await hre.run("verify:verify", { 58 | address: await kpContract.getAddress(), 59 | constructorArgument: kpConstArgs, 60 | }); 61 | 62 | console.log("Verification res: ", verifyImpl); 63 | 64 | // Deploy the transparent proxy 65 | const transparentProxyConstArgs = [ 66 | await kpContract.getAddress(), 67 | proxyAdminContractAddress, 68 | "0x", 69 | ]; 70 | 71 | const transparentUpgradeableProxyFactory = new ContractFactory( 72 | TransparentUpgradeableProxy.abi, 73 | TransparentUpgradeableProxy.bytecode, 74 | proxyAdminWallet 75 | ); 76 | const transparentProxyContract = 77 | await transparentUpgradeableProxyFactory.deploy( 78 | await kpContract.getAddress(), 79 | proxyAdminContractAddress, 80 | "0x" 81 | ); 82 | await transparentProxyContract.waitForDeployment(); 83 | console.log( 84 | "transparentUpgradeableProxy deployed at:", 85 | await transparentProxyContract.getAddress() 86 | ); 87 | 88 | const verifyProxy = await hre.run("verify:verify", { 89 | address: await transparentProxyContract.getAddress(), 90 | constructorArguments: transparentProxyConstArgs, 91 | }); 92 | 93 | console.log("Verification res: ", verifyProxy); 94 | 95 | // Initializing KPV1 contract through proxy 96 | const KP_JSON = require("../../../artifacts-zk/contracts/karmapoint/KPV1.sol/KarmaPointV1.json"); 97 | const KP_ABI = KP_JSON.abi; 98 | 99 | const contract = new Contract( 100 | await transparentProxyContract.getAddress(), 101 | KP_ABI, 102 | contractAdminWallet._signerL2() 103 | ); 104 | 105 | const initializeTx = await contract.initialize(); 106 | await initializeTx.wait(); 107 | 108 | console.log("KPV1 initialization response: ", initializeTx); 109 | } 110 | -------------------------------------------------------------------------------- /contracts/dex/libraries/DexLibrary.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.18; 3 | import "../MultiTokenPoolAmmV1.sol"; 4 | 5 | library DexLibrary { 6 | function getPoolId( 7 | address tokenA, 8 | address tokenB 9 | ) internal pure returns (bytes32) { 10 | (address token0, address token1) = tokenA < tokenB 11 | ? (tokenA, tokenB) 12 | : (tokenB, tokenA); 13 | return keccak256(abi.encodePacked(token0, token1)); 14 | } 15 | 16 | function sqrt(uint256 y) internal pure returns (uint256 z) { 17 | if (y > 3) { 18 | z = y; 19 | uint256 x = y / 2 + 1; 20 | while (x < z) { 21 | z = x; 22 | x = (y / x + x) / 2; 23 | } 24 | } else if (y != 0) { 25 | z = 1; 26 | } 27 | } 28 | 29 | function min(uint256 a, uint256 b) internal pure returns (uint256) { 30 | return a < b ? a : b; 31 | } 32 | 33 | function calculateAmountOut( 34 | uint256 amountIn, 35 | uint256 reserveIn, 36 | uint256 reserveOut, 37 | uint256 feeNumerator, 38 | uint256 feeDenominator, 39 | address tokenIn, 40 | address feeToken // Token from which platform fee is deducted 41 | ) internal pure returns (uint256 amountOut, uint256 platformFee) { 42 | require(amountIn < reserveIn, "Invalid input amount"); 43 | require(reserveIn > 0 && reserveOut > 0, "Insufficient liquidity"); 44 | 45 | if (tokenIn == feeToken) { 46 | uint256 amountInWithFee = amountIn * feeNumerator; 47 | uint256 numerator = amountInWithFee * reserveOut; 48 | uint256 denominator = (reserveIn * feeDenominator) + 49 | amountInWithFee; 50 | 51 | amountOut = numerator / denominator; 52 | platformFee = amountIn - (amountIn * feeNumerator) / feeDenominator; 53 | } else { 54 | uint256 numerator = amountIn * reserveOut; 55 | uint256 denominator = (reserveIn) + amountIn; 56 | 57 | uint256 rawAmountOut = numerator / denominator; 58 | 59 | amountOut = (rawAmountOut * feeNumerator) / feeDenominator; 60 | platformFee = rawAmountOut - amountOut; 61 | } 62 | } 63 | 64 | function calculateAmountIn( 65 | uint256 amountOut, 66 | uint256 reserveIn, 67 | uint256 reserveOut, 68 | uint256 feeNumerator, 69 | uint256 feeDenominator, 70 | address tokenOut, 71 | address feeToken // Token from which platform fee is deducted 72 | ) internal pure returns (uint256 amountIn, uint256 platformFee) { 73 | require(amountOut > 0, "Invalid output amount"); 74 | require(reserveIn > 0 && reserveOut > 0, "Insufficient liquidity"); 75 | 76 | if (tokenOut == feeToken) { 77 | uint256 numerator = reserveIn * amountOut * feeNumerator; 78 | uint256 denominator = (reserveOut - amountOut) * feeDenominator; 79 | 80 | amountIn = numerator / denominator; 81 | platformFee = amountIn - (amountIn * feeNumerator) / feeDenominator; 82 | } else { 83 | uint256 numerator = reserveIn * amountOut * feeDenominator; 84 | uint256 denominator = (reserveOut - amountOut) * feeNumerator; 85 | 86 | uint256 rawAmountIn = numerator / denominator + 1; 87 | 88 | platformFee = 89 | rawAmountIn - 90 | (rawAmountIn * feeNumerator) / 91 | feeDenominator; 92 | amountIn = rawAmountIn; 93 | } 94 | } 95 | 96 | function updateReserves( 97 | MultiTokenPoolAmmV1.Pool storage pool, 98 | address tokenIn, 99 | uint256 amountIn, 100 | uint256 amountOut 101 | ) internal { 102 | if (tokenIn == pool.token0) { 103 | pool.reserve0 += amountIn; 104 | pool.reserve1 -= amountOut; 105 | } else { 106 | pool.reserve1 += amountIn; 107 | pool.reserve0 -= amountOut; 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /interfaces/external/layer-zero/IONFT721CoreUpgradeable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.2; 4 | 5 | import "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol"; 6 | 7 | /** 8 | * @dev Interface of the ONFT Core Upgradeable standard 9 | */ 10 | interface IONFT721CoreUpgradeable is IERC165Upgradeable { 11 | /** 12 | * @dev Emitted when `_tokenIds[]` are moved from the `_sender` to (`_dstChainId`, `_toAddress`) 13 | * `_nonce` is the outbound nonce from 14 | */ 15 | event SendToChain( 16 | uint16 indexed _dstChainId, 17 | address indexed _from, 18 | bytes indexed _toAddress, 19 | uint[] _tokenIds 20 | ); 21 | event ReceiveFromChain( 22 | uint16 indexed _srcChainId, 23 | bytes indexed _srcAddress, 24 | address indexed _toAddress, 25 | uint[] _tokenIds 26 | ); 27 | 28 | /** 29 | * @dev Emitted when `_payload` was received from lz, but not enough gas to deliver all tokenIds 30 | */ 31 | event CreditStored(bytes32 _hashedPayload, bytes _payload); 32 | /** 33 | * @dev Emitted when `_hashedPayload` has been completely delivered 34 | */ 35 | event CreditCleared(bytes32 _hashedPayload); 36 | 37 | /** 38 | * @dev send token `_tokenId` to (`_dstChainId`, `_toAddress`) from `_from` 39 | * `_toAddress` can be any size depending on the `dstChainId`. 40 | * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token) 41 | * `_adapterParams` is a flexible bytes array to indicate messaging adapter services 42 | */ 43 | function sendFrom( 44 | address _from, 45 | uint16 _dstChainId, 46 | bytes calldata _toAddress, 47 | uint _tokenId, 48 | address payable _refundAddress, 49 | address _zroPaymentAddress, 50 | bytes calldata _adapterParams 51 | ) external payable; 52 | 53 | /** 54 | * @dev send tokens `_tokenIds[]` to (`_dstChainId`, `_toAddress`) from `_from` 55 | * `_toAddress` can be any size depending on the `dstChainId`. 56 | * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token) 57 | * `_adapterParams` is a flexible bytes array to indicate messaging adapter services 58 | */ 59 | function sendBatchFrom( 60 | address _from, 61 | uint16 _dstChainId, 62 | bytes calldata _toAddress, 63 | uint[] calldata _tokenIds, 64 | address payable _refundAddress, 65 | address _zroPaymentAddress, 66 | bytes calldata _adapterParams 67 | ) external payable; 68 | 69 | /** 70 | * @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`) 71 | * _dstChainId - L0 defined chain id to send tokens too 72 | * _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain 73 | * _tokenId - token Id to transfer 74 | * _useZro - indicates to use zro to pay L0 fees 75 | * _adapterParams - flexible bytes array to indicate messaging adapter services in L0 76 | */ 77 | function estimateSendFee( 78 | uint16 _dstChainId, 79 | bytes calldata _toAddress, 80 | uint _tokenId, 81 | bool _useZro, 82 | bytes calldata _adapterParams 83 | ) external view returns (uint nativeFee, uint zroFee); 84 | 85 | /** 86 | * @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`) 87 | * _dstChainId - L0 defined chain id to send tokens too 88 | * _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain 89 | * _tokenIds[] - token Ids to transfer 90 | * _useZro - indicates to use zro to pay L0 fees 91 | * _adapterParams - flexible bytes array to indicate messaging adapter services in L0 92 | */ 93 | function estimateSendBatchFee( 94 | uint16 _dstChainId, 95 | bytes calldata _toAddress, 96 | uint[] calldata _tokenIds, 97 | bool _useZro, 98 | bytes calldata _adapterParams 99 | ) external view returns (uint nativeFee, uint zroFee); 100 | } 101 | -------------------------------------------------------------------------------- /lib/external/SafeERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) 3 | 4 | pragma solidity ^0.8.0; 5 | 6 | import "../../interfaces/external/IERC20.sol"; 7 | import "./TWAddress.sol"; 8 | 9 | /** 10 | * @title SafeERC20 11 | * @dev Wrappers around ERC20 operations that throw on failure (when the token 12 | * contract returns false). Tokens that return no value (and instead revert or 13 | * throw on failure) are also supported, non-reverting calls are assumed to be 14 | * successful. 15 | * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, 16 | * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. 17 | */ 18 | library SafeERC20 { 19 | using TWAddress for address; 20 | 21 | function safeTransfer( 22 | IERC20 token, 23 | address to, 24 | uint256 value 25 | ) internal { 26 | _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); 27 | } 28 | 29 | function safeTransferFrom( 30 | IERC20 token, 31 | address from, 32 | address to, 33 | uint256 value 34 | ) internal { 35 | _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); 36 | } 37 | 38 | /** 39 | * @dev Deprecated. This function has issues similar to the ones found in 40 | * {IERC20-approve}, and its usage is discouraged. 41 | * 42 | * Whenever possible, use {safeIncreaseAllowance} and 43 | * {safeDecreaseAllowance} instead. 44 | */ 45 | function safeApprove( 46 | IERC20 token, 47 | address spender, 48 | uint256 value 49 | ) internal { 50 | // safeApprove should only be called when setting an initial allowance, 51 | // or when resetting it to zero. To increase and decrease it, use 52 | // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' 53 | require( 54 | (value == 0) || (token.allowance(address(this), spender) == 0), 55 | "SafeERC20: approve from non-zero to non-zero allowance" 56 | ); 57 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); 58 | } 59 | 60 | function safeIncreaseAllowance( 61 | IERC20 token, 62 | address spender, 63 | uint256 value 64 | ) internal { 65 | uint256 newAllowance = token.allowance(address(this), spender) + value; 66 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 67 | } 68 | 69 | function safeDecreaseAllowance( 70 | IERC20 token, 71 | address spender, 72 | uint256 value 73 | ) internal { 74 | unchecked { 75 | uint256 oldAllowance = token.allowance(address(this), spender); 76 | require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); 77 | uint256 newAllowance = oldAllowance - value; 78 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 79 | } 80 | } 81 | 82 | /** 83 | * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement 84 | * on the return value: the return value is optional (but if data is returned, it must not be false). 85 | * @param token The token targeted by the call. 86 | * @param data The call data (encoded using abi.encode or one of its variants). 87 | */ 88 | function _callOptionalReturn(IERC20 token, bytes memory data) private { 89 | // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since 90 | // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that 91 | // the target address contains contract code and also asserts for success in the low-level call. 92 | 93 | bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); 94 | if (returndata.length > 0) { 95 | // Return data is optional 96 | require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); 97 | } 98 | } 99 | } -------------------------------------------------------------------------------- /deploy/zksync/reformistsphinxv1_deploy.ts: -------------------------------------------------------------------------------- 1 | import { Contract, ContractFactory, Provider, Wallet } from "zksync-ethers"; 2 | import { HardhatRuntimeEnvironment } from "hardhat/types"; 3 | import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; 4 | import * as dotenv from "dotenv"; 5 | 6 | dotenv.config(); 7 | const TransparentUpgradeableProxy = require("../../artifacts-zk/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json"); 8 | 9 | // An example of a deploy script that will deploy and call a simple contract. 10 | export default async function(hre: HardhatRuntimeEnvironment) { 11 | console.log( 12 | `Running deploy script for the upgradable ReformistSphinxV1 contract with transparent proxy...` 13 | ); 14 | 15 | const provider = new Provider(process.env.ZKSYNC_PROVIDER_URI); 16 | await provider.ready; 17 | if (!provider) throw new Error("Please set ZKSYNC_PROVIDER_URI in .env"); 18 | 19 | const proxyAdminContractAddress = process.env.PROXY_ADMIN_CONTRACT_ADDRESS; 20 | if (!proxyAdminContractAddress) 21 | throw new Error("Please set proxyAdminContractAddress"); 22 | 23 | // Initialize the safeWallet. 24 | const proxyAdminWallet = new Wallet( 25 | `${process.env.PROXY_ADMIN_WALLET_PK}`, 26 | provider 27 | ); 28 | console.log( 29 | "proxyAdminWallet address: ", 30 | await proxyAdminWallet.getAddress() 31 | ); 32 | 33 | const contractAdminWallet = new Wallet( 34 | `${process.env.CONTRACT_ADMIN_WALLET_PK}`, 35 | provider 36 | ); 37 | console.log( 38 | "contractAdminWallet address: ", 39 | await contractAdminWallet.getAddress() 40 | ); 41 | 42 | // Initialize deployers 43 | const contractDeployer = new Deployer(hre, contractAdminWallet); 44 | 45 | // Deploy the reformist sphinx contract 46 | const reformistSphinxArtifact = await contractDeployer.loadArtifact( 47 | "ReformistSphinxV1" 48 | ); 49 | const reformistSphinxConstArgs = []; 50 | const reformistSphinxContract = await contractDeployer.deploy( 51 | reformistSphinxArtifact, 52 | reformistSphinxConstArgs 53 | ); 54 | console.log( 55 | "args: " + 56 | reformistSphinxContract.interface.encodeDeploy(reformistSphinxConstArgs) 57 | ); 58 | console.log( 59 | `${reformistSphinxArtifact.contractName} was deployed to ${await reformistSphinxContract.getAddress()}` 60 | ); 61 | 62 | const verifyImpl = await hre.run("verify:verify", { 63 | address: await reformistSphinxContract.getAddress(), 64 | constructorArguments: reformistSphinxConstArgs 65 | }); 66 | 67 | console.log("Verification res: ", verifyImpl); 68 | 69 | // Deploy the transparent proxy 70 | const transparentProxyConstArgs = [ 71 | await reformistSphinxContract.getAddress(), 72 | proxyAdminContractAddress, 73 | "0x" 74 | ]; 75 | const transparentUpgradeableProxyFactory = new ContractFactory( 76 | TransparentUpgradeableProxy.abi, 77 | TransparentUpgradeableProxy.bytecode, 78 | proxyAdminWallet 79 | ); 80 | const transparentProxyContract = await transparentUpgradeableProxyFactory.deploy( 81 | await reformistSphinxContract.getAddress(), 82 | proxyAdminContractAddress, 83 | "0x" 84 | ); 85 | await transparentProxyContract.waitForDeployment(); 86 | console.log( 87 | "transparentUpgradeableProxy deployed at:", 88 | await transparentProxyContract.getAddress() 89 | ); 90 | 91 | const verifyProxy = await hre.run("verify:verify", { 92 | address: await transparentProxyContract.getAddress(), 93 | constructorArguments: transparentProxyConstArgs 94 | }); 95 | 96 | console.log("Verification res: ", verifyProxy); 97 | 98 | console.log(`Initializing reformist sphinx v1 through proxy...`); 99 | 100 | const citizenIdContract = process.env.CITIZEN_ID_CONTRACT_ADDRESS; 101 | if (!citizenIdContract) throw new Error("Please set citizen id address"); 102 | const reformistSphinxIpfsImageUri = 103 | process.env.REFORMIST_SPHINX_IPFS_IMAGE_URI; 104 | if (!reformistSphinxIpfsImageUri) 105 | throw new Error("Please set reformistSphinxIpfsImageUri"); 106 | 107 | const RS_JSON = require("../../artifacts-zk/contracts/guardians/ReformistSphinxV1.sol/ReformistSphinxV1.json"); 108 | const RS_ABI = RS_JSON.abi; 109 | 110 | const rsContract = new Contract( 111 | await transparentProxyContract.getAddress(), 112 | RS_ABI, 113 | contractAdminWallet._signerL2() 114 | ); 115 | 116 | const tx = await rsContract.initialize( 117 | citizenIdContract, 118 | reformistSphinxIpfsImageUri 119 | ); 120 | await tx.wait(); 121 | console.log(tx); 122 | } 123 | -------------------------------------------------------------------------------- /contracts/teva-system/MultiPurposeFeeCollector.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity ^0.8.18; 3 | 4 | import "@openzeppelin/contracts/access/Ownable.sol"; 5 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 6 | import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; 7 | import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; 8 | 9 | contract MultiPurposeFeeCollector is Ownable { 10 | using ECDSA for bytes32; 11 | using SafeERC20 for IERC20; 12 | 13 | address public constant NATIVE_TOKEN = 14 | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; 15 | 16 | // witness address 17 | address private witness; 18 | 19 | // Events 20 | event FeePaid( 21 | address indexed payer, 22 | address indexed token, 23 | uint256 amount, 24 | uint256 purposeId // purpose id defined by the teva system 25 | ); 26 | 27 | event FeePaidSigned( 28 | address indexed payer, 29 | address indexed token, 30 | uint256 amount, 31 | uint256 purposeId // purpose id defined by the teva system 32 | ); 33 | 34 | // constructor 35 | constructor(address _witness) { 36 | witness = _witness; 37 | } 38 | 39 | // Pay fee with ETH 40 | function payWithETH(uint256 purposeId) external payable { 41 | require(msg.value > 0, "Fee must be greater than zero"); 42 | emit FeePaid(msg.sender, NATIVE_TOKEN, msg.value, purposeId); 43 | } 44 | 45 | // Pay fee with ERC20 token 46 | function payWithToken( 47 | address token, 48 | uint256 amount, 49 | uint256 purposeId 50 | ) external { 51 | require(token != address(0), "Invalid token address"); 52 | require(amount > 0, "Fee must be greater than zero"); 53 | 54 | // Transfer the tokens to this contract using SafeERC20 55 | IERC20(token).safeTransferFrom(msg.sender, address(this), amount); 56 | 57 | emit FeePaid(msg.sender, token, amount, purposeId); 58 | } 59 | 60 | // Pay fee with ETH 61 | function payWithETHSigned( 62 | uint256 purposeId, 63 | uint64 validTill, 64 | bytes calldata signature 65 | ) external payable { 66 | require(msg.value > 0, "Fee must be greater than zero"); 67 | verify( 68 | abi.encode(msg.value, purposeId, validTill), 69 | validTill, 70 | signature 71 | ); 72 | emit FeePaidSigned(msg.sender, NATIVE_TOKEN, msg.value, purposeId); 73 | } 74 | 75 | // Pay fee with ERC20 token 76 | function payWithTokenSigned( 77 | address token, 78 | uint256 amount, 79 | uint256 purposeId, 80 | uint64 validTill, 81 | bytes calldata signature 82 | ) external { 83 | require(token != address(0), "Invalid token address"); 84 | require(amount > 0, "Fee must be greater than zero"); 85 | 86 | verify( 87 | abi.encode(token, amount, purposeId, validTill), 88 | validTill, 89 | signature 90 | ); 91 | 92 | // Transfer the tokens to this contract using SafeERC20 93 | IERC20(token).safeTransferFrom(msg.sender, address(this), amount); 94 | 95 | emit FeePaidSigned(msg.sender, token, amount, purposeId); 96 | } 97 | 98 | // Set witness address 99 | function setWitness(address _witness) external onlyOwner { 100 | require(_witness != address(0), "Invalid witness address"); 101 | witness = _witness; 102 | } 103 | 104 | // Verify signature 105 | function verify( 106 | bytes memory data, 107 | uint64 timestamp, 108 | bytes memory signature 109 | ) internal view { 110 | require(timestamp > block.timestamp, "Signature expired"); 111 | require( 112 | keccak256(data).toEthSignedMessageHash().recover(signature) == 113 | witness, 114 | "Invalid signature" 115 | ); 116 | } 117 | 118 | // Withdraw ETH by the owner 119 | function withdrawETH() external onlyOwner { 120 | uint256 balance = address(this).balance; 121 | require(balance > 0, "No ETH to withdraw"); 122 | 123 | (bool success, ) = payable(owner()).call{value: balance}(""); 124 | require(success, "ETH transfer failed"); 125 | } 126 | 127 | // Withdraw ERC20 tokens by the owner 128 | function withdrawTokens(address token) external onlyOwner { 129 | require(token != address(0), "Invalid token address"); 130 | uint256 balance = IERC20(token).balanceOf(address(this)); 131 | require(balance > 0, "No tokens to withdraw"); 132 | IERC20(token).safeTransfer(owner(), balance); 133 | } 134 | 135 | // Fallback to accept ETH 136 | receive() external payable { 137 | emit FeePaid(msg.sender, NATIVE_TOKEN, msg.value, 0); // PurposeId is set to 0 for generic payments 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /contracts/teva-system/SessionAccount.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity ^0.8.18; 3 | 4 | import "@matterlabs/zksync-contracts/l2/system-contracts/interfaces/IAccount.sol"; 5 | import "@matterlabs/zksync-contracts/l2/system-contracts/libraries/TransactionHelper.sol"; 6 | import "@openzeppelin/contracts/access/Ownable.sol"; 7 | import "@openzeppelin/contracts/interfaces/IERC1271.sol"; 8 | import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; 9 | import "@matterlabs/zksync-contracts/l2/system-contracts/Constants.sol"; 10 | import "@matterlabs/zksync-contracts/l2/system-contracts/libraries/SystemContractsCaller.sol"; 11 | 12 | import "./Session.sol"; 13 | 14 | contract SessionAccount is Ownable, Session, IAccount { 15 | using TransactionHelper for Transaction; 16 | 17 | bytes4 constant EIP1271_SUCCESS_RETURN_VALUE = 0x1626ba7e; 18 | 19 | modifier onlyBootloader() { 20 | require( 21 | msg.sender == BOOTLOADER_FORMAL_ADDRESS, 22 | "Only bootloader can call this method" 23 | ); 24 | _; 25 | } 26 | 27 | constructor(address owner) { 28 | _transferOwnership(owner); 29 | } 30 | 31 | function validateTransaction( 32 | bytes32, 33 | bytes32 _suggestedSignedHash, 34 | Transaction calldata _transaction 35 | ) external payable override onlyBootloader returns (bytes4 magic) { 36 | magic = _validateTransaction(_suggestedSignedHash, _transaction); 37 | } 38 | 39 | function _validateTransaction( 40 | bytes32 _suggestedSignedHash, 41 | Transaction calldata _transaction 42 | ) internal returns (bytes4 magic) { 43 | SystemContractsCaller.systemCallWithPropagatedRevert( 44 | uint32(gasleft()), 45 | address(NONCE_HOLDER_SYSTEM_CONTRACT), 46 | 0, 47 | abi.encodeCall( 48 | INonceHolder.incrementMinNonceIfEquals, 49 | (_transaction.nonce) 50 | ) 51 | ); 52 | 53 | bytes32 txHash; 54 | if (_suggestedSignedHash == bytes32(0)) { 55 | txHash = _transaction.encodeHash(); 56 | } else { 57 | txHash = _suggestedSignedHash; 58 | } 59 | 60 | require( 61 | _transaction.signature.length == 65, 62 | "Signature length is incorrect" 63 | ); 64 | 65 | address signer = ECDSA.recover(txHash, _transaction.signature); 66 | 67 | require(owner() == signer || inSession(signer), "Signature is invalid"); 68 | 69 | magic = ACCOUNT_VALIDATION_SUCCESS_MAGIC; 70 | } 71 | 72 | function executeTransaction( 73 | bytes32, 74 | bytes32, 75 | Transaction calldata _transaction 76 | ) external payable override onlyBootloader { 77 | _executeTransaction(_transaction); 78 | } 79 | 80 | function _executeTransaction(Transaction calldata _transaction) internal { 81 | address to = address(uint160(_transaction.to)); 82 | uint128 value = Utils.safeCastToU128(_transaction.value); 83 | bytes memory data = _transaction.data; 84 | 85 | if (to == address(DEPLOYER_SYSTEM_CONTRACT)) { 86 | uint32 gas = Utils.safeCastToU32(gasleft()); 87 | 88 | // Note, that the deployer contract can only be called 89 | // with a "systemCall" flag. 90 | SystemContractsCaller.systemCallWithPropagatedRevert( 91 | gas, 92 | to, 93 | value, 94 | data 95 | ); 96 | } else { 97 | bool success; 98 | assembly { 99 | success := call( 100 | gas(), 101 | to, 102 | value, 103 | add(data, 0x20), 104 | mload(data), 105 | 0, 106 | 0 107 | ) 108 | } 109 | require(success); 110 | } 111 | } 112 | 113 | function executeTransactionFromOutside( 114 | Transaction calldata _transaction 115 | ) external payable { 116 | _validateTransaction(bytes32(0), _transaction); 117 | 118 | _executeTransaction(_transaction); 119 | } 120 | 121 | function payForTransaction( 122 | bytes32, 123 | bytes32, 124 | Transaction calldata _transaction 125 | ) external payable override onlyBootloader { 126 | bool success = _transaction.payToTheBootloader(); 127 | require(success, "Failed to pay the fee to the operator"); 128 | } 129 | 130 | function prepareForPaymaster( 131 | bytes32, 132 | bytes32, 133 | Transaction calldata _transaction 134 | ) external payable override onlyBootloader { 135 | _transaction.processPaymasterInput(); 136 | } 137 | 138 | receive() external payable { 139 | assert(msg.sender != BOOTLOADER_FORMAL_ADDRESS); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /deploy/zksync/multitokenpoolammv1_deploy.ts: -------------------------------------------------------------------------------- 1 | import { Contract, ContractFactory, Provider, Wallet } from "zksync-ethers"; 2 | import { HardhatRuntimeEnvironment } from "hardhat/types"; 3 | import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; 4 | import * as dotenv from "dotenv"; 5 | 6 | dotenv.config(); 7 | const TransparentUpgradeableProxy = require("../../artifacts-zk/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json"); 8 | 9 | // An example of a deploy script that will deploy and call a simple contract. 10 | export default async function (hre: HardhatRuntimeEnvironment) { 11 | console.log( 12 | `Running deploy script for the upgradable MultiTokenPoolAmmV1 contract with transparent proxy...` 13 | ); 14 | 15 | // // environment variables 16 | const provider = new Provider(process.env.ZKSYNC_PROVIDER_URI); 17 | if (!provider) throw new Error("Please set zksync provider url"); 18 | const proxyAdminContractAddress = process.env.PROXY_ADMIN_CONTRACT_ADDRESS; 19 | if (!proxyAdminContractAddress) 20 | throw new Error("Please set proxyAdminContractAddress"); 21 | const tevaTokenContract = process.env.TEVA_TOKEN_CONTRCAT; 22 | if (!tevaTokenContract) throw new Error("Please set tevaTokenContract"); 23 | const kpTokenContract = process.env.KP_TOKEN_CONTRACT; 24 | if (!kpTokenContract) throw new Error("Please set kpTokenContract"); 25 | const trustedCaller = process.env.TRUSTED_CALLER; 26 | if (!trustedCaller) throw new Error("Please set trustedCaller"); 27 | const safeAddress = process.env.SAFE_ADDRESS; 28 | if (!safeAddress) throw new Error("Please set safeAddress"); 29 | 30 | // Initialize the safeWallet. 31 | const proxyAdminWallet = new Wallet( 32 | `${process.env.PROXY_ADMIN_WALLET_PK}`, 33 | provider 34 | ); 35 | console.log( 36 | "proxyAdminWallet address: ", 37 | await proxyAdminWallet.getAddress() 38 | ); 39 | 40 | const contractAdminWallet = new Wallet( 41 | `${process.env.CONTRACT_ADMIN_WALLET_PK}`, 42 | provider 43 | ); 44 | console.log( 45 | "contractAdminWallet address: ", 46 | await contractAdminWallet.getAddress() 47 | ); 48 | 49 | // Initialize deployers 50 | const contractDeployer = new Deployer(hre, contractAdminWallet); 51 | 52 | // Deploy the simplifier kraken contract 53 | const MultiTokenPoolAmmV1Artifact = await contractDeployer.loadArtifact( 54 | "contracts/dex/MultiTokenPoolAmmV1.sol:MultiTokenPoolAmmV1" 55 | ); 56 | const MultiTokenPoolAmmV1ConstArgs = []; 57 | const MultiTokenPoolAmmV1Contract = await contractDeployer.deploy( 58 | MultiTokenPoolAmmV1Artifact, 59 | MultiTokenPoolAmmV1ConstArgs 60 | ); 61 | console.log( 62 | "args: " + 63 | MultiTokenPoolAmmV1Contract.interface.encodeDeploy( 64 | MultiTokenPoolAmmV1ConstArgs 65 | ) 66 | ); 67 | console.log( 68 | `MultiTokenPoolAmmV1 was deployed to ${await MultiTokenPoolAmmV1Contract.getAddress()}` 69 | ); 70 | 71 | const verifyMultiTokenPoolAmmV1 = await hre.run("verify:verify", { 72 | address: await MultiTokenPoolAmmV1Contract.getAddress(), 73 | constructorArguments: MultiTokenPoolAmmV1ConstArgs, 74 | }); 75 | 76 | console.log("Verification res: ", verifyMultiTokenPoolAmmV1); 77 | 78 | // Deploy the transparent proxy 79 | const transparentProxyConstArgs = [ 80 | await MultiTokenPoolAmmV1Contract.getAddress(), 81 | proxyAdminContractAddress, 82 | "0x", 83 | ]; 84 | const transparentUpgradeableProxyFactory = new ContractFactory( 85 | TransparentUpgradeableProxy.abi, 86 | TransparentUpgradeableProxy.bytecode, 87 | proxyAdminWallet 88 | ); 89 | const transparentProxyContract = 90 | await transparentUpgradeableProxyFactory.deploy( 91 | await MultiTokenPoolAmmV1Contract.getAddress(), 92 | proxyAdminContractAddress, 93 | "0x" 94 | ); 95 | await transparentProxyContract.waitForDeployment(); 96 | console.log( 97 | "transparentUpgradeableProxy deployed at:", 98 | await transparentProxyContract.getAddress() 99 | ); 100 | 101 | const verifyProxy = await hre.run("verify:verify", { 102 | address: await transparentProxyContract.getAddress(), 103 | constructorArguments: transparentProxyConstArgs, 104 | }); 105 | 106 | console.log("Verification res: ", verifyProxy); 107 | 108 | // Initializing MultiTokenPoolAmmV1 contract through proxy 109 | const NY_JSON = require("../../artifacts-zk/contracts/dex/MultiTokenPoolAmmV1.sol/MultiTokenPoolAmmV1.json"); 110 | const NY_ABI = NY_JSON.abi; 111 | 112 | const nyContract = new Contract( 113 | await transparentProxyContract.getAddress(), 114 | NY_ABI, 115 | contractAdminWallet._signerL2() 116 | ); 117 | 118 | const initializeMultiTokenPoolAmmV1Tx = await nyContract.initialize(tevaTokenContract, trustedCaller, kpTokenContract, safeAddress); 119 | await initializeMultiTokenPoolAmmV1Tx.wait(); 120 | console.log( 121 | "MultiTokenPoolAmmV1 initialization response: ", 122 | initializeMultiTokenPoolAmmV1Tx 123 | ); 124 | } 125 | -------------------------------------------------------------------------------- /contracts/external/layer-zero/lzApp/NonblockingLzAppUpgradeable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.2; 4 | 5 | import "./LzAppUpgradeable.sol"; 6 | import "../../../../lib/external/layer-zero/ExcessivelySafeCall.sol"; 7 | 8 | /* 9 | * the default LayerZero messaging behaviour is blocking, i.e. any failed message will block the channel 10 | * this abstract class try-catch all fail messages and store locally for future retry. hence, non-blocking 11 | * NOTE: if the srcAddress is not configured properly, it will still block the message pathway from (srcChainId, srcAddress) 12 | */ 13 | abstract contract NonblockingLzAppUpgradeable is 14 | Initializable, 15 | LzAppUpgradeable 16 | { 17 | using ExcessivelySafeCall for address; 18 | 19 | function __NonblockingLzAppUpgradeable_init( 20 | address _endpoint 21 | ) internal onlyInitializing { 22 | __Ownable_init_unchained(); 23 | __LzAppUpgradeable_init_unchained(_endpoint); 24 | } 25 | 26 | function __NonblockingLzAppUpgradeable_init_unchained( 27 | address _endpoint 28 | ) internal onlyInitializing {} 29 | 30 | mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) 31 | public failedMessages; 32 | 33 | event MessageFailed( 34 | uint16 _srcChainId, 35 | bytes _srcAddress, 36 | uint64 _nonce, 37 | bytes _payload, 38 | bytes _reason 39 | ); 40 | event RetryMessageSuccess( 41 | uint16 _srcChainId, 42 | bytes _srcAddress, 43 | uint64 _nonce, 44 | bytes32 _payloadHash 45 | ); 46 | 47 | // overriding the virtual function in LzReceiver 48 | function _blockingLzReceive( 49 | uint16 _srcChainId, 50 | bytes memory _srcAddress, 51 | uint64 _nonce, 52 | bytes memory _payload 53 | ) internal virtual override { 54 | (bool success, bytes memory reason) = address(this).excessivelySafeCall( 55 | gasleft(), 56 | 150, 57 | abi.encodeWithSelector( 58 | this.nonblockingLzReceive.selector, 59 | _srcChainId, 60 | _srcAddress, 61 | _nonce, 62 | _payload 63 | ) 64 | ); 65 | // try-catch all errors/exceptions 66 | if (!success) { 67 | _storeFailedMessage( 68 | _srcChainId, 69 | _srcAddress, 70 | _nonce, 71 | _payload, 72 | reason 73 | ); 74 | } 75 | } 76 | 77 | function _storeFailedMessage( 78 | uint16 _srcChainId, 79 | bytes memory _srcAddress, 80 | uint64 _nonce, 81 | bytes memory _payload, 82 | bytes memory _reason 83 | ) internal virtual { 84 | failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload); 85 | emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload, _reason); 86 | } 87 | 88 | function nonblockingLzReceive( 89 | uint16 _srcChainId, 90 | bytes calldata _srcAddress, 91 | uint64 _nonce, 92 | bytes calldata _payload 93 | ) public virtual { 94 | // only internal transaction 95 | require( 96 | _msgSender() == address(this), 97 | "NonblockingLzApp: caller must be LzApp" 98 | ); 99 | _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload); 100 | } 101 | 102 | //@notice override this function 103 | function _nonblockingLzReceive( 104 | uint16 _srcChainId, 105 | bytes memory _srcAddress, 106 | uint64 _nonce, 107 | bytes memory _payload 108 | ) internal virtual; 109 | 110 | function retryMessage( 111 | uint16 _srcChainId, 112 | bytes calldata _srcAddress, 113 | uint64 _nonce, 114 | bytes calldata _payload 115 | ) public payable virtual { 116 | // assert there is message to retry 117 | bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce]; 118 | require( 119 | payloadHash != bytes32(0), 120 | "NonblockingLzApp: no stored message" 121 | ); 122 | require( 123 | keccak256(_payload) == payloadHash, 124 | "NonblockingLzApp: invalid payload" 125 | ); 126 | // clear the stored message 127 | failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0); 128 | // execute the message. revert if it fails again 129 | _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload); 130 | emit RetryMessageSuccess(_srcChainId, _srcAddress, _nonce, payloadHash); 131 | } 132 | 133 | /** 134 | * @dev This empty reserved space is put in place to allow future versions to add new 135 | * variables without shifting down storage in the inheritance chain. 136 | * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps 137 | */ 138 | uint[49] private __gap; 139 | } 140 | -------------------------------------------------------------------------------- /deploy/zksync/marketplace_deploy.ts: -------------------------------------------------------------------------------- 1 | import { Contract, ContractFactory, Provider, Wallet } from "zksync-ethers"; 2 | import { HardhatRuntimeEnvironment } from "hardhat/types"; 3 | import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; 4 | import * as dotenv from "dotenv"; 5 | 6 | dotenv.config(); 7 | const TransparentUpgradeableProxy = require("../../artifacts-zk/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json"); 8 | 9 | // An example of a deploy script that will deploy and call a simple contract. 10 | export default async function (hre: HardhatRuntimeEnvironment) { 11 | console.log( 12 | `Running deploy script for the upgradable MarketplaceV1 contract with transparent proxy...` 13 | ); 14 | 15 | // environment variables 16 | const provider = new Provider(process.env.ZKSYNC_PROVIDER_URI); 17 | if (!provider) throw new Error("Please set zksync provider url"); 18 | const proxyAdminContractAddress = process.env.PROXY_ADMIN_CONTRACT_ADDRESS; 19 | if (!proxyAdminContractAddress) 20 | throw new Error("Please set proxy admin contract address."); 21 | const marketplaceContractIpfsUrl = process.env.MARKETPLACE_CONTRACT_IPFS_URL; 22 | if (!marketplaceContractIpfsUrl) 23 | throw new Error("Please set marketplace contract address."); 24 | const safeAddress = process.env.SAFE_ADDRESS; 25 | if (!safeAddress) throw new Error("Please set safe address"); 26 | const wethAddress = process.env.WETH_ADDRESS; 27 | if (!wethAddress) throw new Error("Please set wETH address"); 28 | 29 | // Initialize the safeWallet. 30 | const proxyAdminWallet = new Wallet( 31 | `${process.env.PROXY_ADMIN_WALLET_PK}`, 32 | provider 33 | ); 34 | console.log("proxyAdminWallet address: ", await proxyAdminWallet.getAddress()); 35 | 36 | const contractAdminWallet = new Wallet( 37 | `${process.env.CONTRACT_ADMIN_WALLET_PK}`, 38 | provider 39 | ); 40 | console.log("contractAdminWallet address: ", await contractAdminWallet.getAddress()); 41 | 42 | // Initialize deployers 43 | const proxyDeployer = new Deployer(hre, proxyAdminWallet); 44 | const contractDeployer = new Deployer(hre, contractAdminWallet); 45 | 46 | // Deploy the magical marketplaceV1 contract 47 | console.log("Deploying MarketplaceV1..."); 48 | const marketplaceArtifact = await contractDeployer.loadArtifact( 49 | "MarketplaceV1" 50 | ); 51 | const marketplaceConstArgs = [wethAddress]; 52 | const marketplaceContract = await contractDeployer.deploy( 53 | marketplaceArtifact, 54 | marketplaceConstArgs 55 | ); 56 | console.log( 57 | "MarketplaceV1 Constructor Args: " + 58 | marketplaceContract.interface.encodeDeploy(marketplaceConstArgs) 59 | ); 60 | console.log( 61 | `${marketplaceArtifact.contractName} was deployed to ${await marketplaceContract.getAddress()}` 62 | ); 63 | 64 | // verify the magical marketplaceV1 contract 65 | console.log("Verifying MarketplaceV1..."); 66 | await hre.run("verify:verify", { 67 | address: await marketplaceContract.getAddress(), 68 | constructorArguments: marketplaceConstArgs, 69 | }); 70 | 71 | // Deploy the magical marketplace transparent proxy 72 | console.log("Deploying MarketplaceTransparentUpgradeableProxy..."); 73 | const transparentProxyConstArgs = [ 74 | await marketplaceContract.getAddress(), 75 | proxyAdminContractAddress, 76 | "0x", 77 | ]; 78 | const transparentUpgradeableProxyFactory = new ContractFactory( 79 | TransparentUpgradeableProxy.abi, 80 | TransparentUpgradeableProxy.bytecode, 81 | proxyAdminWallet 82 | ); 83 | const transparentProxyContract = 84 | await transparentUpgradeableProxyFactory.deploy( 85 | await marketplaceContract.getAddress(), 86 | proxyAdminContractAddress, 87 | "0x", 88 | ); 89 | await transparentProxyContract.waitForDeployment(); 90 | console.log( 91 | "transparentUpgradeableProxy deployed at:", 92 | await transparentProxyContract.getAddress() 93 | ); 94 | 95 | const verifyProxy = await hre.run("verify:verify", { 96 | address: await transparentProxyContract.getAddress(), 97 | constructorArguments: transparentProxyConstArgs, 98 | }); 99 | 100 | console.log("Verification res: ", verifyProxy); 101 | 102 | console.log( 103 | `Initializing MarketplaceV1 through MarketplaceTransparentUpgradeableProxy...` 104 | ); 105 | 106 | // Initializing magical marketplace contract through proxy 107 | const MP_JSON = require("../../artifacts-zk/contracts/marketplace/MarketplaceV1.sol/MarketplaceV1.json"); 108 | const MP_ABI = MP_JSON.abi; 109 | 110 | const mpContract = new Contract( 111 | await transparentProxyContract.getAddress(), 112 | MP_ABI, 113 | contractAdminWallet._signerL2() 114 | ); 115 | 116 | const initializeMpTx = await mpContract.initialize( 117 | marketplaceContractIpfsUrl, 118 | [], 119 | safeAddress, 120 | process.env.CITIZEN_ID_CONTRACT_ADDRESS 121 | ); 122 | await initializeMpTx.wait(); 123 | console.log("MarketplaceV1 initialization response: ", initializeMpTx); 124 | } 125 | -------------------------------------------------------------------------------- /deploy/zksync/karmapointv1_deploy.ts: -------------------------------------------------------------------------------- 1 | import { Contract, ContractFactory, Provider, Wallet } from "zksync-ethers"; 2 | import { HardhatRuntimeEnvironment } from "hardhat/types"; 3 | import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; 4 | import * as dotenv from "dotenv"; 5 | import { ethers } from "ethers"; 6 | 7 | dotenv.config(); 8 | const TransparentUpgradeableProxy = require("../../artifacts-zk/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json"); 9 | 10 | // An example of a deploy script that will deploy and call a simple contract. 11 | export default async function(hre: HardhatRuntimeEnvironment) { 12 | console.log( 13 | `Running deploy script for the upgradable KarmaPointV1 contract with transparent proxy...` 14 | ); 15 | 16 | const provider = new Provider(process.env.ZKSYNC_PROVIDER_URI); 17 | await provider.ready; 18 | if (!provider) throw new Error("Please set ZKSYNC_PROVIDER_URI in .env"); 19 | const proxyAdminContractAddress = process.env.PROXY_ADMIN_CONTRACT_ADDRESS; 20 | if (!proxyAdminContractAddress) 21 | throw new Error("Please set proxyAdminContractAddress"); 22 | 23 | // Initialize the safeWallet. 24 | const proxyAdminWallet = new Wallet( 25 | `${process.env.PROXY_ADMIN_WALLET_PK}`, 26 | provider 27 | ); 28 | console.log( 29 | "proxyAdminWallet address: ", 30 | await proxyAdminWallet.getAddress() 31 | ); 32 | 33 | const contractAdminWallet = new Wallet( 34 | `${process.env.CONTRACT_ADMIN_WALLET_PK}`, 35 | provider 36 | ); 37 | console.log( 38 | "contractAdminWallet address: ", 39 | await contractAdminWallet.getAddress() 40 | ); 41 | 42 | // Initialize deployers 43 | const contractDeployer = new Deployer(hre, contractAdminWallet); 44 | 45 | // Deploy the karma point contract 46 | const karmaPointArtifact = await contractDeployer.loadArtifact( 47 | "KarmaPointV1" 48 | ); 49 | const karmaPointConstArgs = []; 50 | const karmaPointContract = await contractDeployer.deploy( 51 | karmaPointArtifact, 52 | karmaPointConstArgs 53 | ); 54 | console.log( 55 | "args: " + karmaPointContract.interface.encodeDeploy(karmaPointConstArgs) 56 | ); 57 | console.log( 58 | `${karmaPointArtifact.contractName} was deployed to ${await karmaPointContract.getAddress()}` 59 | ); 60 | 61 | const verifyImplProxy = await hre.run("verify:verify", { 62 | address: await karmaPointContract.getAddress(), 63 | constructorArguments: karmaPointConstArgs 64 | }); 65 | 66 | console.log("Verification res: ", verifyImplProxy); 67 | 68 | // Deploy the transparent proxy 69 | const transparentProxyConstArgs = [ 70 | await karmaPointContract.getAddress(), 71 | proxyAdminContractAddress, 72 | "0x" 73 | ]; 74 | console.log({ 75 | transparentProxyConstArgs, 76 | abi: TransparentUpgradeableProxy.abi, 77 | bytescode: TransparentUpgradeableProxy.bytecode, 78 | proxyAdminWallet 79 | }); 80 | const transparentUpgradeableProxyFactory = new ContractFactory( 81 | TransparentUpgradeableProxy.abi, 82 | TransparentUpgradeableProxy.bytecode, 83 | proxyAdminWallet 84 | ); 85 | const transparentProxyContract = await transparentUpgradeableProxyFactory.deploy( 86 | await karmaPointContract.getAddress(), 87 | proxyAdminContractAddress, 88 | "0x" 89 | ); 90 | await transparentProxyContract.waitForDeployment(); 91 | console.log( 92 | "transparentUpgradeableProxy deployed at:", 93 | await transparentProxyContract.getAddress() 94 | ); 95 | 96 | const verifyProxy = await hre.run("verify:verify", { 97 | address: await transparentProxyContract.getAddress(), 98 | constructorArguments: transparentProxyConstArgs 99 | }); 100 | 101 | console.log("Verification res: ", verifyProxy); 102 | 103 | console.log(`Initializing karma point v1 through proxy...`); 104 | 105 | const citizenIdContract = process.env.CITIZEN_ID_CONTRACT_ADDRESS; 106 | if (!citizenIdContract) throw new Error("Please set citizen id address"); 107 | const safeAddress = process.env.SAFE_ADDRESS; 108 | if (!safeAddress) throw new Error("Please set safeAddress"); 109 | let kpPrice = process.env.KP_PRICE; 110 | if (kpPrice) kpPrice = ethers.parseUnits(kpPrice, 18).toString(); 111 | else throw new Error("please set kp price"); 112 | const kpTotalSupplyCap = process.env.KP_TOTAL_SUPPLY_CAP; 113 | if (!kpTotalSupplyCap) throw new Error("Please set kpTotalSupplyCap"); 114 | const kpBuyCap = process.env.KP_BUY_CAP; 115 | if (!kpBuyCap) throw new Error("Please set kpBuyCap"); 116 | 117 | const KP_JSON = require("../../artifacts-zk/contracts/karmapoint/KarmaPointV1.sol/KarmaPointV1.json"); 118 | const KP_ABI = KP_JSON.abi; 119 | 120 | const kpContract = new Contract( 121 | await transparentProxyContract.getAddress(), 122 | KP_ABI, 123 | contractAdminWallet._signerL2() 124 | ); 125 | 126 | const tx = await kpContract.initialize( 127 | citizenIdContract, 128 | safeAddress, 129 | kpPrice, 130 | kpTotalSupplyCap, 131 | kpBuyCap 132 | ); 133 | await tx.wait(); 134 | console.log(tx); 135 | } 136 | -------------------------------------------------------------------------------- /deploy/zksync/citizenidv1_deploy.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from "dotenv"; 2 | import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; 3 | import { HardhatRuntimeEnvironment } from "hardhat/types"; 4 | import { Contract, ContractFactory, Provider, Wallet } from "zksync-ethers"; 5 | import { ethers } from "ethers"; 6 | 7 | dotenv.config(); 8 | const TransparentUpgradeableProxy = require("../../artifacts-zk/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json"); 9 | 10 | // An example of a deploy script that will deploy and call a simple contract. 11 | export default async function(hre: HardhatRuntimeEnvironment) { 12 | console.log( 13 | `Running deploy script for the upgradable CitizenIV1 contract with transparent proxy...` 14 | ); 15 | 16 | // environment variables 17 | const provider = new Provider(process.env.ZKSYNC_PROVIDER_URI); 18 | await provider.ready; 19 | if (!provider) throw new Error("Please set ZKSYNC_PROVIDER_URI in .env"); 20 | 21 | const citizenIdIpfsBaseUri = process.env.CITIZEN_ID_IPFS_BASE_URI; 22 | if (!citizenIdIpfsBaseUri) 23 | throw new Error("Please set CITIZEN_ID_IPFS_BASE_URI in .env"); 24 | 25 | let citizenIdPrice = process.env.CITIZEN_ID_PRICE; 26 | if (citizenIdPrice) 27 | citizenIdPrice = ethers.parseUnits(citizenIdPrice, 18).toString(); 28 | else throw new Error("Please set citizen id price"); 29 | 30 | // Initialize the safeWallet. 31 | const proxyAdminWallet = new Wallet( 32 | `${process.env.PROXY_ADMIN_WALLET_PK}`, 33 | provider 34 | ); 35 | console.log( 36 | "proxyAdminWallet address: ", 37 | await proxyAdminWallet.getAddress() 38 | ); 39 | 40 | const contractAdminWallet = new Wallet( 41 | `${process.env.CONTRACT_ADMIN_WALLET_PK}`, 42 | provider 43 | ); 44 | console.log( 45 | "contractAdminWallet address: ", 46 | await contractAdminWallet.getAddress() 47 | ); 48 | 49 | // // Initialize deployers 50 | const proxyDeployer = new Deployer(hre, proxyAdminWallet); 51 | const contractDeployer = new Deployer(hre, contractAdminWallet); 52 | 53 | // Deploy the proxy admin 54 | const proxyAdminArtifact = await proxyDeployer.loadArtifact( 55 | "contracts/proxy/transparent/ProxyAdmin.sol:ProxyAdmin" 56 | ); 57 | const proxyAdminConstArgs = []; 58 | const proxyAdminContract = await proxyDeployer.deploy( 59 | proxyAdminArtifact, 60 | proxyAdminConstArgs 61 | ); 62 | console.log( 63 | "args: " + proxyAdminContract.interface.encodeDeploy(proxyAdminConstArgs) 64 | ); 65 | console.log( 66 | `${proxyAdminArtifact.contractName} was deployed to ${await proxyAdminContract.getAddress()}` 67 | ); 68 | 69 | const proxyVerifyRes = await hre.run("verify:verify", { 70 | address: await proxyAdminContract.getAddress(), 71 | constructorArguments: proxyAdminConstArgs, 72 | }); 73 | 74 | console.log("Verification res: ", proxyVerifyRes); 75 | 76 | // Deploy the citizen id contract 77 | const citizenIdArtifact = await contractDeployer.loadArtifact("CitizenIDV1"); 78 | const citizenIdConstArgs = []; 79 | const citizenIdContract = await contractDeployer.deploy( 80 | citizenIdArtifact, 81 | citizenIdConstArgs 82 | ); 83 | console.log( 84 | "args: " + citizenIdContract.interface.encodeDeploy(citizenIdConstArgs) 85 | ); 86 | console.log( 87 | `${citizenIdArtifact.contractName} was deployed to ${await citizenIdContract.getAddress()}` 88 | ); 89 | 90 | // const res = await hre.run("verify:verify", { 91 | // address: await citizenIdContract.getAddress(), 92 | // constructorArguments: citizenIdConstArgs, 93 | // }); 94 | 95 | // console.log("Verification res: ", res); 96 | 97 | // Deploy the transparent proxy 98 | const transparentProxyConstArgs = [ 99 | await citizenIdContract.getAddress(), 100 | await proxyAdminContract.getAddress(), 101 | "0x" 102 | ]; 103 | console.log({ bytecode: TransparentUpgradeableProxy.bytecode }); 104 | const transparentUpgradeableProxyFactory = new ContractFactory( 105 | TransparentUpgradeableProxy.abi, 106 | TransparentUpgradeableProxy.bytecode, 107 | proxyAdminWallet 108 | ); 109 | const transparentProxyContract = await transparentUpgradeableProxyFactory.deploy( 110 | await citizenIdContract.getAddress(), 111 | await proxyAdminContract.getAddress(), 112 | "0x" 113 | ); 114 | await transparentProxyContract.waitForDeployment(); 115 | console.log( 116 | "transparentUpgradeableProxy deployed at:", 117 | await transparentProxyContract.getAddress() 118 | ); 119 | 120 | const verifyProxy = await hre.run("verify:verify", { 121 | address: await transparentProxyContract.getAddress(), 122 | constructorArguments: transparentProxyConstArgs 123 | }); 124 | 125 | console.log("Verification res: ", verifyProxy); 126 | 127 | // Initializing citizen id contract through proxy 128 | const CZ_JSON = require("../../artifacts-zk/contracts/citizenid/CitizenIDV1.sol/CitizenIDV1.json"); 129 | const CZ_ABI = CZ_JSON.abi; 130 | 131 | const czContract = new Contract( 132 | await transparentProxyContract.getAddress(), 133 | CZ_ABI, 134 | contractAdminWallet._signerL2() 135 | ); 136 | 137 | const initializeCitizenIdTx = await czContract.initialize( 138 | citizenIdIpfsBaseUri, 139 | citizenIdPrice 140 | ); 141 | await initializeCitizenIdTx.wait(); 142 | console.log("CitizenIDV1 initialization response: ", initializeCitizenIdTx); 143 | } 144 | -------------------------------------------------------------------------------- /deploy/zksync/magicalphoenixv1_deploy.ts: -------------------------------------------------------------------------------- 1 | import { Contract, ContractFactory, Provider, Wallet } from "zksync-ethers"; 2 | import { HardhatRuntimeEnvironment } from "hardhat/types"; 3 | import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; 4 | import * as dotenv from "dotenv"; 5 | 6 | dotenv.config(); 7 | const TransparentUpgradeableProxy = require("../../artifacts-zk/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json"); 8 | 9 | // An example of a deploy script that will deploy and call a simple contract. 10 | export default async function (hre: HardhatRuntimeEnvironment) { 11 | console.log( 12 | `Running deploy script for the upgradable MagicalPhoenixV1 contract with transparent proxy...` 13 | ); 14 | 15 | // environment variables 16 | const provider = new Provider(process.env.ZKSYNC_PROVIDER_URI); 17 | if (!provider) throw new Error("Please set zksync provider url"); 18 | const proxyAdminContractAddress = process.env.PROXY_ADMIN_CONTRACT_ADDRESS; 19 | if (!proxyAdminContractAddress) 20 | throw new Error("Please set proxy admin contract address."); 21 | const citizenIdContract = process.env.CITIZEN_ID_CONTRACT_ADDRESS; 22 | if (!citizenIdContract) 23 | throw new Error("Please set citizen id contract address."); 24 | const magicalPhoenixIpfsBaseUri = process.env.MAGICAL_PHOENIX_IPFS_BASE_URI; 25 | if (!magicalPhoenixIpfsBaseUri) 26 | throw new Error("Please set magical phoenix ipfs base url."); 27 | const magicalPhoenixIpfsContractUri = 28 | process.env.MAGICAL_PHOENIX_IPFS_CONTRACT_URI; 29 | if (!magicalPhoenixIpfsContractUri) 30 | throw new Error("Please set magical phoenix ipfs contract url."); 31 | const safeAddress = process.env.SAFE_ADDRESS; 32 | if (!safeAddress) throw new Error("Please set safe address"); 33 | 34 | // Initialize the safeWallet. 35 | const proxyAdminWallet = new Wallet( 36 | `${process.env.PROXY_ADMIN_WALLET_PK}`, 37 | provider 38 | ); 39 | console.log("proxyAdminWallet address: ", await proxyAdminWallet.getAddress()); 40 | 41 | const contractAdminWallet = new Wallet( 42 | `${process.env.CONTRACT_ADMIN_WALLET_PK}`, 43 | provider 44 | ); 45 | console.log("contractAdminWallet address: ", await contractAdminWallet.getAddress()); 46 | 47 | // Initialize deployers 48 | const proxyDeployer = new Deployer(hre, proxyAdminWallet); 49 | const contractDeployer = new Deployer(hre, contractAdminWallet); 50 | 51 | // Deploy the magical phoenixV1 contract 52 | console.log("Deploying MagicalPhoenixV1..."); 53 | const magicalPhoenixArtifact = await contractDeployer.loadArtifact( 54 | "MagicalPhoenixV1" 55 | ); 56 | const magicalPhoenixConstArgs = []; 57 | const magicalPhoenixContract = await contractDeployer.deploy( 58 | magicalPhoenixArtifact, 59 | magicalPhoenixConstArgs 60 | ); 61 | console.log( 62 | "MagicalPhoenixV1 Constructor Args: " + 63 | magicalPhoenixContract.interface.encodeDeploy(magicalPhoenixConstArgs) 64 | ); 65 | console.log( 66 | `${magicalPhoenixArtifact.contractName} was deployed to ${await magicalPhoenixContract.getAddress()}` 67 | ); 68 | 69 | // verify the magical phoenixV1 contract 70 | console.log("Verifying MagicalPhoenixV1..."); 71 | await hre.run("verify:verify", { 72 | address: await magicalPhoenixContract.getAddress(), 73 | constructorArguments: magicalPhoenixConstArgs, 74 | }); 75 | 76 | // Deploy the magical phoenix transparent proxy 77 | console.log("Deploying MagicalPhoenixTransparentUpgradeableProxy..."); 78 | const transparentProxyConstArgs = [ 79 | await magicalPhoenixContract.getAddress(), 80 | proxyAdminContractAddress, 81 | "0x", 82 | ]; 83 | const transparentUpgradeableProxyFactory = new ContractFactory( 84 | TransparentUpgradeableProxy.abi, 85 | TransparentUpgradeableProxy.bytecode, 86 | proxyAdminWallet 87 | ); 88 | const transparentProxyContract = 89 | await transparentUpgradeableProxyFactory.deploy( 90 | await magicalPhoenixContract.getAddress(), 91 | proxyAdminContractAddress, 92 | "0x", 93 | ); 94 | await transparentProxyContract.waitForDeployment(); 95 | console.log( 96 | "transparentUpgradeableProxy deployed at:", 97 | await transparentProxyContract.getAddress() 98 | ); 99 | 100 | const verifyProxy = await hre.run("verify:verify", { 101 | address: await transparentProxyContract.getAddress(), 102 | constructorArguments: transparentProxyConstArgs, 103 | }); 104 | 105 | console.log("Verification res: ", verifyProxy); 106 | 107 | console.log( 108 | `Initializing MagicalPhoenixV1 through MagicalPhoenixTransparentUpgradeableProxy...` 109 | ); 110 | 111 | // Initializing magical phoenix contract through proxy 112 | const MP_JSON = require("../../artifacts-zk/contracts/guardians/MagicalPhoenixV1.sol/MagicalPhoenixV1.json"); 113 | const MP_ABI = MP_JSON.abi; 114 | 115 | const mpContract = new Contract( 116 | await transparentProxyContract.getAddress(), 117 | MP_ABI, 118 | contractAdminWallet._signerL2() 119 | ); 120 | 121 | console.log({citizenIdContract, 122 | magicalPhoenixIpfsContractUri, 123 | magicalPhoenixIpfsBaseUri, 124 | safeAddress}); 125 | 126 | const initializeMpTx = await mpContract.initialize( 127 | citizenIdContract, 128 | magicalPhoenixIpfsContractUri, 129 | magicalPhoenixIpfsBaseUri, 130 | safeAddress 131 | ); 132 | await initializeMpTx.wait(); 133 | console.log("MagicalPhoenixV1 initialization response: ", initializeMpTx); 134 | } 135 | -------------------------------------------------------------------------------- /contracts/guardians/ReformistSphinxV2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.18; 3 | 4 | import "../citizenid/CitizenIDV1.sol"; 5 | import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; 6 | import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; 7 | import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; 8 | import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; 9 | import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721RoyaltyUpgradeable.sol"; 10 | import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol"; 11 | import "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol"; 12 | 13 | /// @title ReformistSphinx NFT contract 14 | /// @author Tevaera Labs 15 | /// @notice Allows users to mint the guardian NFT of ReformistSphinx 16 | /// @dev It extends ERC721 and ERC2981 standards 17 | contract ReformistSphinxV2 is 18 | ERC721RoyaltyUpgradeable, 19 | ERC721URIStorageUpgradeable, 20 | ERC721EnumerableUpgradeable, 21 | OwnableUpgradeable, 22 | PausableUpgradeable, 23 | ReentrancyGuardUpgradeable 24 | { 25 | using CountersUpgradeable for CountersUpgradeable.Counter; 26 | 27 | CitizenIDV1 private citizenIdContract; 28 | CountersUpgradeable.Counter private tokenIdCounter; 29 | 30 | modifier isNotBlacklisted() { 31 | require( 32 | !citizenIdContract.blacklisted(msg.sender), 33 | "Tevan Blacklisted!" 34 | ); 35 | _; 36 | } 37 | 38 | modifier isTevan() { 39 | require(citizenIdContract.balanceOf(msg.sender) > 0, "Not a Tevan"); 40 | _; 41 | } 42 | 43 | string public tokenImageUri; 44 | 45 | mapping(address => bool) private addressToHasMintedMap; 46 | 47 | /// @dev the token base uri 48 | string private tokenBaseUri; 49 | 50 | /// @dev Initializes the upgradable contract 51 | /// @param _citizenIdContract the citizen id contract address 52 | /// @param _tokenImageUri the token image uri 53 | function initialize( 54 | CitizenIDV1 _citizenIdContract, 55 | string calldata _tokenImageUri 56 | ) external initializer { 57 | __ERC721_init("ReformistSphinx", "SPHINX"); 58 | __ERC721Enumerable_init(); 59 | __ERC721Royalty_init(); 60 | __Ownable_init(); 61 | __Pausable_init(); 62 | __ReentrancyGuard_init(); 63 | 64 | citizenIdContract = _citizenIdContract; 65 | tokenImageUri = _tokenImageUri; 66 | 67 | // increament the counter 68 | tokenIdCounter.increment(); 69 | 70 | // set default royalty to 5% 71 | _setDefaultRoyalty(msg.sender, 500); 72 | } 73 | 74 | /// @dev Mints Guardian NFT 75 | function mint() 76 | external 77 | isTevan 78 | isNotBlacklisted 79 | whenNotPaused 80 | nonReentrant 81 | { 82 | // make sure caller has not already minted 83 | require(addressToHasMintedMap[msg.sender] == false, "already minted"); 84 | 85 | // get the token id & update the counter 86 | uint256 tokenId = tokenIdCounter.current(); 87 | tokenIdCounter.increment(); 88 | 89 | // mint the guardian nft 90 | _mint(msg.sender, tokenId); 91 | 92 | // mark address as minted 93 | addressToHasMintedMap[msg.sender] = true; 94 | } 95 | 96 | /// @dev Sets the token base uri 97 | /// @param _tokenBaseUri the token base uri 98 | function setTokenBaseUri( 99 | string calldata _tokenBaseUri 100 | ) external onlyOwner whenNotPaused { 101 | tokenBaseUri = _tokenBaseUri; 102 | } 103 | 104 | // ----- system default functions ----- 105 | 106 | /// @dev Allows owner to pause sale if active 107 | function pause() public onlyOwner whenNotPaused { 108 | _pause(); 109 | } 110 | 111 | /// @dev Allows owner to activate sale 112 | function unpause() public onlyOwner whenPaused { 113 | _unpause(); 114 | } 115 | 116 | function _burn( 117 | uint256 tokenId 118 | ) 119 | internal 120 | override( 121 | ERC721Upgradeable, 122 | ERC721RoyaltyUpgradeable, 123 | ERC721URIStorageUpgradeable 124 | ) 125 | { 126 | super._burn(tokenId); 127 | } 128 | 129 | function _beforeTokenTransfer( 130 | address from, 131 | address to, 132 | uint256 tokenId, 133 | uint256 batchSize 134 | ) 135 | internal 136 | override(ERC721Upgradeable, ERC721EnumerableUpgradeable) 137 | whenNotPaused 138 | { 139 | super._beforeTokenTransfer(from, to, tokenId, batchSize); 140 | } 141 | 142 | function supportsInterface( 143 | bytes4 interfaceId 144 | ) 145 | public 146 | view 147 | override( 148 | ERC721RoyaltyUpgradeable, 149 | ERC721EnumerableUpgradeable, 150 | ERC721URIStorageUpgradeable 151 | ) 152 | returns (bool) 153 | { 154 | return super.supportsInterface(interfaceId); 155 | } 156 | 157 | function _baseURI() 158 | internal 159 | view 160 | override(ERC721Upgradeable) 161 | returns (string memory) 162 | { 163 | return tokenBaseUri; 164 | } 165 | 166 | function tokenURI( 167 | uint256 tokenId 168 | ) 169 | public 170 | view 171 | override(ERC721Upgradeable, ERC721URIStorageUpgradeable) 172 | returns (string memory) 173 | { 174 | return super.tokenURI(tokenId); 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /deploy/zksync/nomadicyetiv1_deploy.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "ethers"; 2 | import { Contract, ContractFactory, Provider, Wallet } from "zksync-ethers"; 3 | import { HardhatRuntimeEnvironment } from "hardhat/types"; 4 | import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; 5 | import * as dotenv from "dotenv"; 6 | 7 | dotenv.config(); 8 | const TransparentUpgradeableProxy = require("../../artifacts-zk/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json"); 9 | 10 | // An example of a deploy script that will deploy and call a simple contract. 11 | export default async function (hre: HardhatRuntimeEnvironment) { 12 | console.log( 13 | `Running deploy script for the upgradable NomadicYetiV1 contract with transparent proxy...` 14 | ); 15 | 16 | // environment variables 17 | const provider = new Provider(process.env.ZKSYNC_PROVIDER_URI); 18 | if (!provider) throw new Error("Please set zksync provider url"); 19 | const proxyAdminContractAddress = process.env.PROXY_ADMIN_CONTRACT_ADDRESS; 20 | if (!proxyAdminContractAddress) 21 | throw new Error("Please set proxyAdminContractAddress"); 22 | const layerzeroZkSyncEndpoint = process.env.LAYERZERO_ZKSYNC_ENDPOINT; 23 | if (!layerzeroZkSyncEndpoint) 24 | throw new Error("Please set zksync layer zero endpoint"); 25 | const safeAddress = process.env.SAFE_ADDRESS; 26 | if (!safeAddress) throw new Error("Please set safe address"); 27 | const crosschainTransferFee = ethers.parseEther( 28 | process.env.CROSSCHAIN_TRANSFER_FEE as string 29 | ); 30 | if (!crosschainTransferFee) throw new Error("Please set crosschain fee"); 31 | const minGasToTransferAndStore = ethers.parseEther( 32 | process.env.MIN_GAS_TO_TRANSFER_AND_STORE as string 33 | ); 34 | if (!minGasToTransferAndStore) 35 | throw new Error("Please set minGasToTransferAndStore"); 36 | const singleGuardianPrice = ethers.parseEther( 37 | process.env.SINGLE_GUARDIAN_PRICE as string 38 | ); 39 | if (!singleGuardianPrice) throw new Error("Please set singleGuardianPrice"); 40 | const nomadicYetiIpfsContractUri = process.env.NOMADIC_YETI_IPFS_CONTRACT_URI; 41 | if (!nomadicYetiIpfsContractUri) 42 | throw new Error("Please set nomadicYetiIpfsContractUri"); 43 | const nomadicYetiIpfsBaseUri = process.env.NOMADIC_YETI_IPFS_BASE_URI; 44 | if (!nomadicYetiIpfsBaseUri) 45 | throw new Error("Please set nomadicYetiIpfsBaseUri"); 46 | 47 | // Initialize the safeWallet. 48 | const proxyAdminWallet = new Wallet( 49 | `${process.env.PROXY_ADMIN_WALLET_PK}`, 50 | provider 51 | ); 52 | console.log("proxyAdminWallet address: ", await proxyAdminWallet.getAddress()); 53 | 54 | const contractAdminWallet = new Wallet( 55 | `${process.env.CONTRACT_ADMIN_WALLET_PK}`, 56 | provider 57 | ); 58 | console.log("contractAdminWallet address: ", await contractAdminWallet.getAddress()); 59 | 60 | // Initialize deployers 61 | const proxyDeployer = new Deployer(hre, proxyAdminWallet); 62 | const contractDeployer = new Deployer(hre, contractAdminWallet); 63 | 64 | // Deploy the nomadic yeti contract 65 | const nomadicYetiArtifact = await contractDeployer.loadArtifact( 66 | "contracts/guardians/NomadicYetiV1.sol:NomadicYetiV1" 67 | ); 68 | const nomadicYetiConstArgs = []; 69 | const nomadicYetiContract = await contractDeployer.deploy( 70 | nomadicYetiArtifact, 71 | nomadicYetiConstArgs 72 | ); 73 | console.log( 74 | "args: " + nomadicYetiContract.interface.encodeDeploy(nomadicYetiConstArgs) 75 | ); 76 | console.log( 77 | `${nomadicYetiArtifact.contractName} was deployed to ${await nomadicYetiContract.getAddress()}` 78 | ); 79 | 80 | const verifyImpl = await hre.run("verify:verify", { 81 | address: await nomadicYetiContract.getAddress(), 82 | constructorArguments: nomadicYetiConstArgs 83 | }); 84 | 85 | console.log("Verification res: ", verifyImpl); 86 | 87 | // Deploy the transparent proxy 88 | const transparentProxyConstArgs = [ 89 | await nomadicYetiContract.getAddress(), 90 | proxyAdminContractAddress, 91 | "0x" 92 | ]; 93 | const transparentUpgradeableProxyFactory = new ContractFactory( 94 | TransparentUpgradeableProxy.abi, 95 | TransparentUpgradeableProxy.bytecode, 96 | proxyAdminWallet 97 | ); 98 | const transparentProxyContract = 99 | await transparentUpgradeableProxyFactory.deploy( 100 | await nomadicYetiContract.getAddress(), 101 | proxyAdminContractAddress, 102 | "0x" 103 | ); 104 | await transparentProxyContract.waitForDeployment(); 105 | console.log( 106 | "transparentUpgradeableProxy deployed at:", 107 | await transparentProxyContract.getAddress() 108 | ); 109 | 110 | const verifyProxy = await hre.run("verify:verify", { 111 | address: await transparentProxyContract.getAddress(), 112 | constructorArguments: transparentProxyConstArgs, 113 | }); 114 | 115 | console.log("Verification res: ", verifyProxy); 116 | 117 | // Initializing NomadicYetiV1 contract through proxy 118 | const NY_JSON = require("../../artifacts-zk/contracts/guardians/NomadicYetiV1.sol/NomadicYetiV1.json"); 119 | const NY_ABI = NY_JSON.abi; 120 | 121 | const nyContract = new Contract( 122 | await transparentProxyContract.getAddress(), 123 | NY_ABI, 124 | contractAdminWallet._signerL2() 125 | ); 126 | 127 | const initializeMpTx = await nyContract.initialize( 128 | layerzeroZkSyncEndpoint, 129 | safeAddress, 130 | crosschainTransferFee, 131 | minGasToTransferAndStore, 132 | singleGuardianPrice, 133 | nomadicYetiIpfsContractUri, 134 | nomadicYetiIpfsBaseUri 135 | ); 136 | await initializeMpTx.wait(); 137 | console.log("NomadicYetiV1 initialization response: ", initializeMpTx); 138 | } 139 | -------------------------------------------------------------------------------- /deploy/zksync/balancerdragonv1_deploy.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "ethers"; 2 | import { Contract, ContractFactory, Provider, Wallet } from "zksync-ethers"; 3 | import { HardhatRuntimeEnvironment } from "hardhat/types"; 4 | import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; 5 | import * as dotenv from "dotenv"; 6 | 7 | dotenv.config(); 8 | const TransparentUpgradeableProxy = require("../../artifacts-zk/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json"); 9 | 10 | // An example of a deploy script that will deploy and call a simple contract. 11 | export default async function (hre: HardhatRuntimeEnvironment) { 12 | console.log( 13 | `Running deploy script for the upgradable BalancerDragonV1 contract with transparent proxy...` 14 | ); 15 | 16 | // environment variables 17 | const provider = new Provider(process.env.ZKSYNC_PROVIDER_URI); 18 | if (!provider) throw new Error("Please set zksync provider url"); 19 | const proxyAdminContractAddress = process.env.PROXY_ADMIN_CONTRACT_ADDRESS; 20 | if (!proxyAdminContractAddress) 21 | throw new Error("Please set proxyAdminContractAddress"); 22 | const layerzeroZkSyncEndpoint = process.env.LAYERZERO_ZKSYNC_ENDPOINT; 23 | if (!layerzeroZkSyncEndpoint) 24 | throw new Error("Please set zksync layer zero endpoint"); 25 | const safeAddress = process.env.SAFE_ADDRESS; 26 | if (!safeAddress) throw new Error("Please set safe address"); 27 | const crosschainTransferFee = ethers.parseEther( 28 | process.env.CROSSCHAIN_TRANSFER_FEE as string 29 | ); 30 | if (!crosschainTransferFee) throw new Error("Please set crosschain fee"); 31 | const minGasToTransferAndStore = ethers.parseEther( 32 | process.env.MIN_GAS_TO_TRANSFER_AND_STORE as string 33 | ); 34 | if (!minGasToTransferAndStore) 35 | throw new Error("Please set minGasToTransferAndStore"); 36 | const singleGuardianPrice = ethers.parseEther( 37 | process.env.SINGLE_GUARDIAN_PRICE as string 38 | ); 39 | if (!singleGuardianPrice) throw new Error("Please set singleGuardianPrice"); 40 | const balancerDragonIpfsContractUri = 41 | process.env.BALANCER_DRAGON_IPFS_CONTRACT_URI; 42 | if (!balancerDragonIpfsContractUri) 43 | throw new Error("Please set balancerDragonIpfsContractUri"); 44 | const balancerDragonIpfsBaseUri = process.env.BALANCER_DRAGON_IPFS_BASE_URI; 45 | if (!balancerDragonIpfsBaseUri) 46 | throw new Error("Please set balancerDragonIpfsBaseUri"); 47 | 48 | // Initialize the safeWallet. 49 | const proxyAdminWallet = new Wallet( 50 | `${process.env.PROXY_ADMIN_WALLET_PK}`, 51 | provider 52 | ); 53 | console.log("proxyAdminWallet address: ", await proxyAdminWallet.getAddress()); 54 | 55 | const contractAdminWallet = new Wallet( 56 | `${process.env.CONTRACT_ADMIN_WALLET_PK}`, 57 | provider 58 | ); 59 | console.log("contractAdminWallet address: ", await contractAdminWallet.getAddress()); 60 | 61 | // Initialize deployers 62 | const proxyDeployer = new Deployer(hre, proxyAdminWallet); 63 | const contractDeployer = new Deployer(hre, contractAdminWallet); 64 | 65 | // Deploy the balancer dragon contract 66 | const balancerDragonArtifact = await contractDeployer.loadArtifact( 67 | "contracts/guardians/BalancerDragonV1.sol:BalancerDragonV1" 68 | ); 69 | const balancerDragonConstArgs = []; 70 | const balancerDragonContract = await contractDeployer.deploy( 71 | balancerDragonArtifact, 72 | balancerDragonConstArgs 73 | ); 74 | console.log( 75 | "args: " + 76 | balancerDragonContract.interface.encodeDeploy(balancerDragonConstArgs) 77 | ); 78 | console.log( 79 | `${balancerDragonArtifact.contractName} was deployed to ${await balancerDragonContract.getAddress()}` 80 | ); 81 | 82 | const verifyImpl = await hre.run("verify:verify", { 83 | address: await balancerDragonContract.getAddress(), 84 | constructorArgument: balancerDragonConstArgs, 85 | }); 86 | 87 | console.log("Verification res: ", verifyImpl); 88 | 89 | // Deploy the transparent proxy 90 | const transparentProxyConstArgs = [ 91 | await balancerDragonContract.getAddress(), 92 | proxyAdminContractAddress, 93 | "0x" 94 | ]; 95 | 96 | const transparentUpgradeableProxyFactory = new ContractFactory( 97 | TransparentUpgradeableProxy.abi, 98 | TransparentUpgradeableProxy.bytecode, 99 | proxyAdminWallet 100 | ); 101 | const transparentProxyContract = 102 | await transparentUpgradeableProxyFactory.deploy( 103 | await balancerDragonContract.getAddress(), 104 | proxyAdminContractAddress, 105 | "0x" 106 | ); 107 | await transparentProxyContract.waitForDeployment(); 108 | console.log( 109 | "transparentUpgradeableProxy deployed at:", 110 | await transparentProxyContract.getAddress() 111 | ); 112 | 113 | const verifyProxy = await hre.run("verify:verify", { 114 | address: await transparentProxyContract.getAddress(), 115 | constructorArguments: transparentProxyConstArgs, 116 | }); 117 | 118 | console.log("Verification res: ", verifyProxy); 119 | 120 | // Initializing BalancerDragonV1 contract through proxy 121 | const NY_JSON = require("../../artifacts-zk/contracts/guardians/BalancerDragonV1.sol/BalancerDragonV1.json"); 122 | const NY_ABI = NY_JSON.abi; 123 | 124 | const nyContract = new Contract( 125 | await transparentProxyContract.getAddress(), 126 | NY_ABI, 127 | contractAdminWallet._signerL2() 128 | ); 129 | 130 | const initializeMpTx = await nyContract.initialize( 131 | layerzeroZkSyncEndpoint, 132 | safeAddress, 133 | crosschainTransferFee, 134 | minGasToTransferAndStore, 135 | singleGuardianPrice, 136 | balancerDragonIpfsContractUri, 137 | balancerDragonIpfsBaseUri 138 | ); 139 | await initializeMpTx.wait(); 140 | console.log("BalancerDragonV1 initialization response: ", initializeMpTx); 141 | } 142 | -------------------------------------------------------------------------------- /deploy/zksync/simplifierkrakenv1_deploy.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "ethers"; 2 | import { Contract, ContractFactory, Provider, Wallet } from "zksync-ethers"; 3 | import { HardhatRuntimeEnvironment } from "hardhat/types"; 4 | import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; 5 | import * as dotenv from "dotenv"; 6 | 7 | dotenv.config(); 8 | const TransparentUpgradeableProxy = require("../../artifacts-zk/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json"); 9 | 10 | // An example of a deploy script that will deploy and call a simple contract. 11 | export default async function (hre: HardhatRuntimeEnvironment) { 12 | console.log( 13 | `Running deploy script for the upgradable SimplifierKrakenV1 contract with transparent proxy...` 14 | ); 15 | 16 | // environment variables 17 | const provider = new Provider(process.env.ZKSYNC_PROVIDER_URI); 18 | if (!provider) throw new Error("Please set zksync provider url"); 19 | const proxyAdminContractAddress = process.env.PROXY_ADMIN_CONTRACT_ADDRESS; 20 | if (!proxyAdminContractAddress) 21 | throw new Error("Please set proxyAdminContractAddress"); 22 | const layerzeroZkSyncEndpoint = process.env.LAYERZERO_ZKSYNC_ENDPOINT; 23 | if (!layerzeroZkSyncEndpoint) 24 | throw new Error("Please set zksync layer zero endpoint"); 25 | const safeAddress = process.env.SAFE_ADDRESS; 26 | if (!safeAddress) throw new Error("Please set safe address"); 27 | const crosschainTransferFee = ethers.parseEther( 28 | process.env.CROSSCHAIN_TRANSFER_FEE as string 29 | ); 30 | if (!crosschainTransferFee) throw new Error("Please set crosschain fee"); 31 | const minGasToTransferAndStore = ethers.parseEther( 32 | process.env.MIN_GAS_TO_TRANSFER_AND_STORE as string 33 | ); 34 | if (!minGasToTransferAndStore) 35 | throw new Error("Please set minGasToTransferAndStore"); 36 | const singleGuardianPrice = ethers.parseEther( 37 | process.env.SINGLE_GUARDIAN_PRICE as string 38 | ); 39 | if (!singleGuardianPrice) throw new Error("Please set singleGuardianPrice"); 40 | const simplifierKrakenIpfsContractUri = 41 | process.env.SIMPLIFIER_KRAKEN_IPFS_CONTRACT_URI; 42 | if (!simplifierKrakenIpfsContractUri) 43 | throw new Error("Please set simplifierKrakenIpfsContractUri"); 44 | const simplifierKrakenIpfsBaseUri = 45 | process.env.SIMPLIFIER_KRAKEN_IPFS_BASE_URI; 46 | if (!simplifierKrakenIpfsBaseUri) 47 | throw new Error("Please set simplifierKrakenIpfsBaseUri"); 48 | 49 | // Initialize the safeWallet. 50 | const proxyAdminWallet = new Wallet( 51 | `${process.env.PROXY_ADMIN_WALLET_PK}`, 52 | provider 53 | ); 54 | console.log("proxyAdminWallet address: ", await proxyAdminWallet.getAddress()); 55 | 56 | const contractAdminWallet = new Wallet( 57 | `${process.env.CONTRACT_ADMIN_WALLET_PK}`, 58 | provider 59 | ); 60 | console.log("contractAdminWallet address: ", await contractAdminWallet.getAddress()); 61 | 62 | // Initialize deployers 63 | const proxyDeployer = new Deployer(hre, proxyAdminWallet); 64 | const contractDeployer = new Deployer(hre, contractAdminWallet); 65 | 66 | // Deploy the simplifier kraken contract 67 | const simplifierKrakenArtifact = await contractDeployer.loadArtifact( 68 | "contracts/guardians/SimplifierKrakenV1.sol:SimplifierKrakenV1" 69 | ); 70 | const simplifierKrakenConstArgs = []; 71 | const simplifierKrakenContract = await contractDeployer.deploy( 72 | simplifierKrakenArtifact, 73 | simplifierKrakenConstArgs 74 | ); 75 | console.log( 76 | "args: " + 77 | simplifierKrakenContract.interface.encodeDeploy(simplifierKrakenConstArgs) 78 | ); 79 | console.log( 80 | `${simplifierKrakenArtifact.contractName} was deployed to ${await simplifierKrakenContract.getAddress()}` 81 | ); 82 | 83 | const verifyKraken = await hre.run("verify:verify", { 84 | address: await simplifierKrakenContract.getAddress(), 85 | constructorArguments: simplifierKrakenConstArgs 86 | }); 87 | 88 | console.log("Verification res: ", verifyKraken); 89 | 90 | // Deploy the transparent proxy 91 | const transparentProxyConstArgs = [ 92 | await simplifierKrakenContract.getAddress(), 93 | proxyAdminContractAddress, 94 | "0x" 95 | ]; 96 | const transparentUpgradeableProxyFactory = new ContractFactory( 97 | TransparentUpgradeableProxy.abi, 98 | TransparentUpgradeableProxy.bytecode, 99 | proxyAdminWallet 100 | ); 101 | const transparentProxyContract = 102 | await transparentUpgradeableProxyFactory.deploy( 103 | await simplifierKrakenContract.getAddress(), 104 | proxyAdminContractAddress, 105 | "0x" 106 | ); 107 | await transparentProxyContract.waitForDeployment(); 108 | console.log( 109 | "transparentUpgradeableProxy deployed at:", 110 | await transparentProxyContract.getAddress() 111 | ); 112 | 113 | const verifyProxy = await hre.run("verify:verify", { 114 | address: await transparentProxyContract.getAddress(), 115 | constructorArguments: transparentProxyConstArgs, 116 | }); 117 | 118 | console.log("Verification res: ", verifyProxy); 119 | 120 | // Initializing SimplifierKrakenV1 contract through proxy 121 | const NY_JSON = require("../../artifacts-zk/contracts/guardians/SimplifierKrakenV1.sol/SimplifierKrakenV1.json"); 122 | const NY_ABI = NY_JSON.abi; 123 | 124 | const nyContract = new Contract( 125 | await transparentProxyContract.getAddress(), 126 | NY_ABI, 127 | contractAdminWallet._signerL2() 128 | ); 129 | 130 | const initializeMpTx = await nyContract.initialize( 131 | layerzeroZkSyncEndpoint, 132 | safeAddress, 133 | crosschainTransferFee, 134 | minGasToTransferAndStore, 135 | singleGuardianPrice, 136 | simplifierKrakenIpfsContractUri, 137 | simplifierKrakenIpfsBaseUri 138 | ); 139 | await initializeMpTx.wait(); 140 | console.log("SimplifierKrakenV1 initialization response: ", initializeMpTx); 141 | } 142 | -------------------------------------------------------------------------------- /deploy/zksync/innovativeunicornv1_deploy.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "ethers"; 2 | import { Contract, ContractFactory, Provider, Wallet } from "zksync-ethers"; 3 | import { HardhatRuntimeEnvironment } from "hardhat/types"; 4 | import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; 5 | import * as dotenv from "dotenv"; 6 | 7 | dotenv.config(); 8 | const TransparentUpgradeableProxy = require("../../artifacts-zk/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json"); 9 | 10 | // An example of a deploy script that will deploy and call a simple contract. 11 | export default async function (hre: HardhatRuntimeEnvironment) { 12 | console.log( 13 | `Running deploy script for the upgradable InnovativeUnicornV1 contract with transparent proxy...` 14 | ); 15 | 16 | // environment variables 17 | const provider = new Provider(process.env.ZKSYNC_PROVIDER_URI); 18 | if (!provider) throw new Error("Please set zksync provider url"); 19 | const proxyAdminContractAddress = process.env.PROXY_ADMIN_CONTRACT_ADDRESS; 20 | if (!proxyAdminContractAddress) 21 | throw new Error("Please set proxyAdminContractAddress"); 22 | const layerzeroZkSyncEndpoint = process.env.LAYERZERO_ZKSYNC_ENDPOINT; 23 | if (!layerzeroZkSyncEndpoint) 24 | throw new Error("Please set zksync layer zero endpoint"); 25 | const safeAddress = process.env.SAFE_ADDRESS; 26 | if (!safeAddress) throw new Error("Please set safe address"); 27 | const crosschainTransferFee = ethers.parseEther( 28 | process.env.CROSSCHAIN_TRANSFER_FEE as string 29 | ); 30 | if (!crosschainTransferFee) throw new Error("Please set crosschain fee"); 31 | const minGasToTransferAndStore = ethers.parseEther( 32 | process.env.MIN_GAS_TO_TRANSFER_AND_STORE as string 33 | ); 34 | if (!minGasToTransferAndStore) 35 | throw new Error("Please set minGasToTransferAndStore"); 36 | const singleGuardianPrice = ethers.parseEther( 37 | process.env.SINGLE_GUARDIAN_PRICE as string 38 | ); 39 | if (!singleGuardianPrice) throw new Error("Please set singleGuardianPrice"); 40 | const innovativeUnicornIpfsContractUri = 41 | process.env.INNOVATIVE_UNICORN_IPFS_CONTRACT_URI; 42 | if (!innovativeUnicornIpfsContractUri) 43 | throw new Error("Please set innovativeUnicornIpfsContractUri"); 44 | const innovativeUnicornIpfsBaseUri = 45 | process.env.INNOVATIVE_UNICORN_IPFS_BASE_URI; 46 | if (!innovativeUnicornIpfsBaseUri) 47 | throw new Error("Please set innovativeUnicornIpfsBaseUri"); 48 | 49 | // Initialize the safeWallet. 50 | const proxyAdminWallet = new Wallet( 51 | `${process.env.PROXY_ADMIN_WALLET_PK}`, 52 | provider 53 | ); 54 | console.log("proxyAdminWallet address: ", await proxyAdminWallet.getAddress()); 55 | 56 | const contractAdminWallet = new Wallet( 57 | `${process.env.CONTRACT_ADMIN_WALLET_PK}`, 58 | provider 59 | ); 60 | console.log("contractAdminWallet address: ", await contractAdminWallet.getAddress()); 61 | 62 | // Initialize deployers 63 | const proxyDeployer = new Deployer(hre, proxyAdminWallet); 64 | const contractDeployer = new Deployer(hre, contractAdminWallet); 65 | 66 | // Deploy the innovative unicorn contract 67 | const innovativeUnicornArtifact = await contractDeployer.loadArtifact( 68 | "contracts/guardians/InnovativeUnicornV1.sol:InnovativeUnicornV1" 69 | ); 70 | const innovativeUnicornConstArgs = []; 71 | const innovativeUnicornContract = await contractDeployer.deploy( 72 | innovativeUnicornArtifact, 73 | innovativeUnicornConstArgs 74 | ); 75 | console.log( 76 | "args: " + 77 | innovativeUnicornContract.interface.encodeDeploy( 78 | innovativeUnicornConstArgs 79 | ) 80 | ); 81 | console.log( 82 | `${innovativeUnicornArtifact.contractName} was deployed to ${await innovativeUnicornContract.getAddress()}` 83 | ); 84 | 85 | const verifyImpl = await hre.run("verify:verify", { 86 | address: await innovativeUnicornContract.getAddress(), 87 | constructorArguments: innovativeUnicornConstArgs 88 | }); 89 | 90 | console.log("Verification res: ", verifyImpl); 91 | 92 | // Deploy the transparent proxy 93 | const transparentProxyConstArgs = [ 94 | await innovativeUnicornContract.getAddress(), 95 | proxyAdminContractAddress, 96 | "0x" 97 | ]; 98 | const transparentUpgradeableProxyFactory = new ContractFactory( 99 | TransparentUpgradeableProxy.abi, 100 | TransparentUpgradeableProxy.bytecode, 101 | proxyAdminWallet 102 | ); 103 | const transparentProxyContract = 104 | await transparentUpgradeableProxyFactory.deploy( 105 | await innovativeUnicornContract.getAddress(), 106 | proxyAdminContractAddress, 107 | "0x" 108 | ); 109 | await transparentProxyContract.waitForDeployment(); 110 | console.log( 111 | "transparentUpgradeableProxy deployed at:", 112 | await transparentProxyContract.getAddress() 113 | ); 114 | 115 | const verifyProxy = await hre.run("verify:verify", { 116 | address: await transparentProxyContract.getAddress(), 117 | constructorArguments: transparentProxyConstArgs, 118 | }); 119 | 120 | console.log("Verification res: ", verifyProxy); 121 | 122 | // Initializing InnovativeUnicornV1 contract through proxy 123 | const NY_JSON = require("../../artifacts-zk/contracts/guardians/InnovativeUnicornV1.sol/InnovativeUnicornV1.json"); 124 | const NY_ABI = NY_JSON.abi; 125 | 126 | const nyContract = new Contract( 127 | await transparentProxyContract.getAddress(), 128 | NY_ABI, 129 | contractAdminWallet._signerL2() 130 | ); 131 | 132 | const initializeMpTx = await nyContract.initialize( 133 | layerzeroZkSyncEndpoint, 134 | safeAddress, 135 | crosschainTransferFee, 136 | minGasToTransferAndStore, 137 | singleGuardianPrice, 138 | innovativeUnicornIpfsContractUri, 139 | innovativeUnicornIpfsBaseUri 140 | ); 141 | await initializeMpTx.wait(); 142 | console.log("InnovativeUnicornV1 initialization response: ", initializeMpTx); 143 | } 144 | -------------------------------------------------------------------------------- /lib/external/layer-zero/ExcessivelySafeCall.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity >=0.7.6; 3 | 4 | library ExcessivelySafeCall { 5 | uint256 constant LOW_28_MASK = 6 | 0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff; 7 | 8 | /// @notice Use when you _really_ really _really_ don't trust the called 9 | /// contract. This prevents the called contract from causing reversion of 10 | /// the caller in as many ways as we can. 11 | /// @dev The main difference between this and a solidity low-level call is 12 | /// that we limit the number of bytes that the callee can cause to be 13 | /// copied to caller memory. This prevents stupid things like malicious 14 | /// contracts returning 10,000,000 bytes causing a local OOG when copying 15 | /// to memory. 16 | /// @param _target The address to call 17 | /// @param _gas The amount of gas to forward to the remote contract 18 | /// @param _maxCopy The maximum number of bytes of returndata to copy 19 | /// to memory. 20 | /// @param _calldata The data to send to the remote contract 21 | /// @return success and returndata, as `.call()`. Returndata is capped to 22 | /// `_maxCopy` bytes. 23 | function excessivelySafeCall( 24 | address _target, 25 | uint256 _gas, 26 | uint16 _maxCopy, 27 | bytes memory _calldata 28 | ) internal returns (bool, bytes memory) { 29 | // set up for assembly call 30 | uint256 _toCopy; 31 | bool _success; 32 | bytes memory _returnData = new bytes(_maxCopy); 33 | // dispatch message to recipient 34 | // by assembly calling "handle" function 35 | // we call via assembly to avoid memcopying a very large returndata 36 | // returned by a malicious contract 37 | assembly { 38 | _success := call( 39 | _gas, // gas 40 | _target, // recipient 41 | 0, // ether value 42 | add(_calldata, 0x20), // inloc 43 | mload(_calldata), // inlen 44 | 0, // outloc 45 | 0 // outlen 46 | ) 47 | // limit our copy to 256 bytes 48 | _toCopy := returndatasize() 49 | if gt(_toCopy, _maxCopy) { 50 | _toCopy := _maxCopy 51 | } 52 | // Store the length of the copied bytes 53 | mstore(_returnData, _toCopy) 54 | // copy the bytes from returndata[0:_toCopy] 55 | returndatacopy(add(_returnData, 0x20), 0, _toCopy) 56 | } 57 | return (_success, _returnData); 58 | } 59 | 60 | /// @notice Use when you _really_ really _really_ don't trust the called 61 | /// contract. This prevents the called contract from causing reversion of 62 | /// the caller in as many ways as we can. 63 | /// @dev The main difference between this and a solidity low-level call is 64 | /// that we limit the number of bytes that the callee can cause to be 65 | /// copied to caller memory. This prevents stupid things like malicious 66 | /// contracts returning 10,000,000 bytes causing a local OOG when copying 67 | /// to memory. 68 | /// @param _target The address to call 69 | /// @param _gas The amount of gas to forward to the remote contract 70 | /// @param _maxCopy The maximum number of bytes of returndata to copy 71 | /// to memory. 72 | /// @param _calldata The data to send to the remote contract 73 | /// @return success and returndata, as `.call()`. Returndata is capped to 74 | /// `_maxCopy` bytes. 75 | function excessivelySafeStaticCall( 76 | address _target, 77 | uint256 _gas, 78 | uint16 _maxCopy, 79 | bytes memory _calldata 80 | ) internal view returns (bool, bytes memory) { 81 | // set up for assembly call 82 | uint256 _toCopy; 83 | bool _success; 84 | bytes memory _returnData = new bytes(_maxCopy); 85 | // dispatch message to recipient 86 | // by assembly calling "handle" function 87 | // we call via assembly to avoid memcopying a very large returndata 88 | // returned by a malicious contract 89 | assembly { 90 | _success := staticcall( 91 | _gas, // gas 92 | _target, // recipient 93 | add(_calldata, 0x20), // inloc 94 | mload(_calldata), // inlen 95 | 0, // outloc 96 | 0 // outlen 97 | ) 98 | // limit our copy to 256 bytes 99 | _toCopy := returndatasize() 100 | if gt(_toCopy, _maxCopy) { 101 | _toCopy := _maxCopy 102 | } 103 | // Store the length of the copied bytes 104 | mstore(_returnData, _toCopy) 105 | // copy the bytes from returndata[0:_toCopy] 106 | returndatacopy(add(_returnData, 0x20), 0, _toCopy) 107 | } 108 | return (_success, _returnData); 109 | } 110 | 111 | /** 112 | * @notice Swaps function selectors in encoded contract calls 113 | * @dev Allows reuse of encoded calldata for functions with identical 114 | * argument types but different names. It simply swaps out the first 4 bytes 115 | * for the new selector. This function modifies memory in place, and should 116 | * only be used with caution. 117 | * @param _newSelector The new 4-byte selector 118 | * @param _buf The encoded contract args 119 | */ 120 | function swapSelector(bytes4 _newSelector, bytes memory _buf) 121 | internal 122 | pure 123 | { 124 | require(_buf.length >= 4); 125 | uint256 _mask = LOW_28_MASK; 126 | assembly { 127 | // load the first word of 128 | let _word := mload(add(_buf, 0x20)) 129 | // mask out the top 4 bytes 130 | // /x 131 | _word := and(_word, _mask) 132 | _word := or(_newSelector, _word) 133 | mstore(add(_buf, 0x20), _word) 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /deploy/zksync/guardianbundlerv1_deploy.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "ethers"; 2 | import { Contract, ContractFactory, Provider, Wallet } from "zksync-ethers"; 3 | import { HardhatRuntimeEnvironment } from "hardhat/types"; 4 | import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; 5 | import * as dotenv from "dotenv"; 6 | 7 | dotenv.config(); 8 | const TransparentUpgradeableProxy = require("../../artifacts-zk/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json"); 9 | 10 | // An example of a deploy script that will deploy and call a simple contract. 11 | export default async function (hre: HardhatRuntimeEnvironment) { 12 | console.log( 13 | `Running deploy script for the upgradable GuardianBundlerV1 contract with transparent proxy...` 14 | ); 15 | 16 | // environment variables 17 | const provider = new Provider(process.env.ZKSYNC_PROVIDER_URI); 18 | if (!provider) throw new Error("Please set zksync provider url"); 19 | const proxyAdminContractAddress = process.env.PROXY_ADMIN_CONTRACT_ADDRESS; 20 | if (!proxyAdminContractAddress) 21 | throw new Error("Please set proxyAdminContractAddress"); 22 | const nomadicYetiContractAddress = 23 | process.env.ZKSYNC_NOMADIC_YETI_CONTRACT_ADDRESS; 24 | if (!nomadicYetiContractAddress) 25 | throw new Error("Please set nomadicYetiContractAddress"); 26 | const balancerDragonContractAddress = 27 | process.env.ZKSYNC_BALANCER_DRAGON_CONTRACT_ADDRESS; 28 | if (!balancerDragonContractAddress) 29 | throw new Error("Please set balancerDragonContractAddress"); 30 | const influentialWerewolfContractAddress = 31 | process.env.ZKSYNC_INFLUENTIAL_WEREWOLF_CONTRACT_ADDRESS; 32 | if (!influentialWerewolfContractAddress) 33 | throw new Error("Please set influentialWerewolfContractAddress"); 34 | const innovativeUnicornContractAddress = 35 | process.env.ZKSYNC_INNOVATIVE_UNICORN_CONTRACT_ADDRESS; 36 | if (!innovativeUnicornContractAddress) 37 | throw new Error("Please set innovativeUnicornContractAddress"); 38 | const simplifierKrakenContractAddress = 39 | process.env.ZKSYNC_SIMPLIFIER_KRAKEN_CONTRACT_ADDRESS; 40 | if (!simplifierKrakenContractAddress) 41 | throw new Error("Please set simplifierKrakenContractAddress"); 42 | const safeAddress = process.env.SAFE_ADDRESS; 43 | if (!safeAddress) throw new Error("Please set safe address"); 44 | const bundleGuardianPrice = ethers.parseEther( 45 | process.env.BUNDLE_GUARDIAN_PRICE as string 46 | ); 47 | if (!bundleGuardianPrice) throw new Error("Please set bundleGuardianPrice"); 48 | 49 | // Initialize the safeWallet. 50 | const proxyAdminWallet = new Wallet( 51 | `${process.env.PROXY_ADMIN_WALLET_PK}`, 52 | provider 53 | ); 54 | console.log("proxyAdminWallet address: ", await proxyAdminWallet.getAddress()); 55 | 56 | const contractAdminWallet = new Wallet( 57 | `${process.env.CONTRACT_ADMIN_WALLET_PK}`, 58 | provider 59 | ); 60 | console.log("contractAdminWallet address: ", await contractAdminWallet.getAddress()); 61 | 62 | // Initialize deployers 63 | const proxyDeployer = new Deployer(hre, proxyAdminWallet); 64 | const contractDeployer = new Deployer(hre, contractAdminWallet); 65 | 66 | // Deploy the gunadian bundler contract 67 | const guardianBundlerArtifact = await contractDeployer.loadArtifact( 68 | "contracts/guardians/GuardianBundlerV1.sol:GuardianBundlerV1" 69 | ); 70 | const guardianBundlerConstArgs = []; 71 | const guardianBundlerContract = await contractDeployer.deploy( 72 | guardianBundlerArtifact, 73 | guardianBundlerConstArgs 74 | ); 75 | console.log( 76 | "args: " + 77 | guardianBundlerContract.interface.encodeDeploy(guardianBundlerConstArgs) 78 | ); 79 | console.log( 80 | `${guardianBundlerArtifact.contractName} was deployed to ${await guardianBundlerContract.getAddress()}` 81 | ); 82 | 83 | const verifyImpl = await hre.run("verify:verify", { 84 | address: await guardianBundlerContract.getAddress(), 85 | constructorArguments: guardianBundlerConstArgs 86 | }); 87 | 88 | console.log("Verification res: ", verifyImpl); 89 | 90 | // Deploy the transparent proxy 91 | const transparentProxyConstArgs = [ 92 | await guardianBundlerContract.getAddress(), 93 | proxyAdminContractAddress, 94 | "0x" 95 | ]; 96 | const transparentUpgradeableProxyFactory = new ContractFactory( 97 | TransparentUpgradeableProxy.abi, 98 | TransparentUpgradeableProxy.bytecode, 99 | proxyAdminWallet 100 | ); 101 | const transparentProxyContract = 102 | await transparentUpgradeableProxyFactory.deploy( 103 | await guardianBundlerContract.getAddress(), 104 | proxyAdminContractAddress, 105 | "0x" 106 | ); 107 | await transparentProxyContract.waitForDeployment(); 108 | console.log( 109 | "transparentUpgradeableProxy deployed at:", 110 | await transparentProxyContract.getAddress() 111 | ); 112 | 113 | const verifyProxy = await hre.run("verify:verify", { 114 | address: await transparentProxyContract.getAddress(), 115 | constructorArguments: transparentProxyConstArgs, 116 | }); 117 | 118 | console.log("Verification res: ", verifyProxy); 119 | 120 | // Initializing GuardianBundlerV1 contract through proxy 121 | const NY_JSON = require("../../artifacts-zk/contracts/guardians/GuardianBundlerV1.sol/GuardianBundlerV1.json"); 122 | const NY_ABI = NY_JSON.abi; 123 | 124 | const nyContract = new Contract( 125 | await transparentProxyContract.getAddress(), 126 | NY_ABI, 127 | contractAdminWallet._signerL2() 128 | ); 129 | 130 | const initializeMpTx = await nyContract.initialize( 131 | balancerDragonContractAddress, 132 | influentialWerewolfContractAddress, 133 | innovativeUnicornContractAddress, 134 | nomadicYetiContractAddress, 135 | simplifierKrakenContractAddress, 136 | safeAddress, 137 | bundleGuardianPrice 138 | ); 139 | await initializeMpTx.wait(); 140 | console.log("GuardianBundlerV1 initialization response: ", initializeMpTx); 141 | } 142 | -------------------------------------------------------------------------------- /contracts/guardians/GuardianBundlerV1.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.18; 3 | 4 | import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; 5 | import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; 6 | import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; 7 | import "./BalancerDragonV1.sol"; 8 | import "./InfluentialWerewolfV1.sol"; 9 | import "./InnovativeUnicornV1.sol"; 10 | import "./NomadicYetiV1.sol"; 11 | import "./SimplifierKrakenV1.sol"; 12 | 13 | /// @title Airdrop claim contract for Citizen ID & Karma Points 14 | /// @author Tevaera Labs 15 | /// @notice Claims airdropped Citizen ID & Karma Points 16 | /// @dev Uses CitizenID and KarmaPoint contracts for minting 17 | contract GuardianBundlerV1 is OwnableUpgradeable, PausableUpgradeable { 18 | /// @dev the safe address 19 | address payable private safeAddress; 20 | 21 | /// @dev the instances of guardian contracts 22 | BalancerDragonV1 internal balancerDragon; 23 | InfluentialWerewolfV1 internal influentialWerewolf; 24 | InnovativeUnicornV1 internal innovativeUnicorn; 25 | NomadicYetiV1 internal nomadicYeti; 26 | SimplifierKrakenV1 internal simplifierKraken; 27 | 28 | /// @dev the bundle price in ETH 29 | uint256 public bundlePrice; 30 | 31 | function initialize( 32 | BalancerDragonV1 _balancerDragon, 33 | InfluentialWerewolfV1 _influentialWerewolf, 34 | InnovativeUnicornV1 _innovativeUnicorn, 35 | NomadicYetiV1 _nomadicYeti, 36 | SimplifierKrakenV1 _simplifierKraken, 37 | address _safeAddress, 38 | uint256 _bundlePrice 39 | ) external initializer { 40 | balancerDragon = _balancerDragon; 41 | influentialWerewolf = _influentialWerewolf; 42 | innovativeUnicorn = _innovativeUnicorn; 43 | nomadicYeti = _nomadicYeti; 44 | simplifierKraken = _simplifierKraken; 45 | safeAddress = payable(_safeAddress); 46 | bundlePrice = _bundlePrice; 47 | } 48 | 49 | /// @notice Users gets citizen id and karma points if eligible 50 | /// @dev Mints citizen id and karma points 51 | function mintBundle() external payable whenNotPaused { 52 | // price validation 53 | require(msg.value == bundlePrice, "Invalid amount"); 54 | 55 | // mint all guardians 56 | if (balancerDragon.balanceOf(msg.sender) == 0) { 57 | balancerDragon.mintForBundler(msg.sender); 58 | } 59 | if (influentialWerewolf.balanceOf(msg.sender) == 0) { 60 | influentialWerewolf.mintForBundler(msg.sender); 61 | } 62 | if (innovativeUnicorn.balanceOf(msg.sender) == 0) { 63 | innovativeUnicorn.mintForBundler(msg.sender); 64 | } 65 | if (nomadicYeti.balanceOf(msg.sender) == 0) { 66 | nomadicYeti.mintForBundler(msg.sender); 67 | } 68 | if (simplifierKraken.balanceOf(msg.sender) == 0) { 69 | simplifierKraken.mintForBundler(msg.sender); 70 | } 71 | } 72 | 73 | /// @dev Owner can update the citizen id contract address 74 | function setBalancerDragon( 75 | BalancerDragonV1 _balancerDragon 76 | ) external onlyOwner { 77 | balancerDragon = _balancerDragon; 78 | } 79 | 80 | /// @dev Owner can update the citizen id contract address 81 | function setInfluentialWerewolf( 82 | InfluentialWerewolfV1 _influentialWerewolf 83 | ) external onlyOwner { 84 | influentialWerewolf = _influentialWerewolf; 85 | } 86 | 87 | /// @dev Owner can update the citizen id contract address 88 | function setInnovativeUnicorn( 89 | InnovativeUnicornV1 _innovativeUnicorn 90 | ) external onlyOwner { 91 | innovativeUnicorn = _innovativeUnicorn; 92 | } 93 | 94 | /// @dev Owner can update the citizen id contract address 95 | function setNomadicYeti(NomadicYetiV1 _nomadicYeti) external onlyOwner { 96 | nomadicYeti = _nomadicYeti; 97 | } 98 | 99 | /// @dev Owner can update the citizen id contract address 100 | function setSimplifierKraken( 101 | SimplifierKrakenV1 _simplifierKraken 102 | ) external onlyOwner { 103 | simplifierKraken = _simplifierKraken; 104 | } 105 | 106 | /// @dev Allows owner to update the safe wallet address 107 | /// @param _safeAddress the safe wallet address 108 | function updateSafeAddress( 109 | address payable _safeAddress 110 | ) external onlyOwner { 111 | require(_safeAddress != address(0), "Invalid address!"); 112 | safeAddress = _safeAddress; 113 | } 114 | 115 | /// @dev Withdraws the funds 116 | function withdraw(address token, uint256 amount) external onlyOwner { 117 | if (token == address(0)) { 118 | // Withdraw Ether 119 | require( 120 | address(this).balance >= amount, 121 | "Insufficient Ether balance" 122 | ); 123 | 124 | // Transfer Ether to the owner 125 | (bool success, ) = payable(msg.sender).call{value: amount}(""); 126 | require(success, "Ether transfer failed"); 127 | } else { 128 | // Withdraw ERC-20 tokens 129 | IERC20Upgradeable erc20Token = IERC20Upgradeable(token); 130 | uint256 contractBalance = erc20Token.balanceOf(address(this)); 131 | require(contractBalance >= amount, "Insufficient token balance"); 132 | 133 | // Transfer ERC-20 tokens to the owner 134 | require( 135 | erc20Token.transfer(msg.sender, amount), 136 | "Token transfer failed" 137 | ); 138 | } 139 | } 140 | 141 | /// @dev Owner can pause the claim 142 | function pause() external onlyOwner whenNotPaused { 143 | _pause(); 144 | } 145 | 146 | /// @dev Owner can activate the claim 147 | function unpause() external onlyOwner whenPaused { 148 | _unpause(); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /deploy/zksync/influentialwerewolfv1_deploy.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "ethers"; 2 | import { Contract, ContractFactory, Provider, Wallet } from "zksync-ethers"; 3 | import { HardhatRuntimeEnvironment } from "hardhat/types"; 4 | import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; 5 | import * as dotenv from "dotenv"; 6 | 7 | dotenv.config(); 8 | const TransparentUpgradeableProxy = require("../../artifacts-zk/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json"); 9 | 10 | // An example of a deploy script that will deploy and call a simple contract. 11 | export default async function (hre: HardhatRuntimeEnvironment) { 12 | console.log( 13 | `Running deploy script for the upgradable InfluentialWerewolfV1 contract with transparent proxy...` 14 | ); 15 | 16 | // environment variables 17 | const provider = new Provider(process.env.ZKSYNC_PROVIDER_URI); 18 | if (!provider) throw new Error("Please set zksync provider url"); 19 | const proxyAdminContractAddress = process.env.PROXY_ADMIN_CONTRACT_ADDRESS; 20 | if (!proxyAdminContractAddress) 21 | throw new Error("Please set proxyAdminContractAddress"); 22 | const layerzeroZkSyncEndpoint = process.env.LAYERZERO_ZKSYNC_ENDPOINT; 23 | if (!layerzeroZkSyncEndpoint) 24 | throw new Error("Please set zksync layer zero endpoint"); 25 | const safeAddress = process.env.SAFE_ADDRESS; 26 | if (!safeAddress) throw new Error("Please set safe address"); 27 | const crosschainTransferFee = ethers.parseEther( 28 | process.env.CROSSCHAIN_TRANSFER_FEE as string 29 | ); 30 | if (!crosschainTransferFee) throw new Error("Please set crosschain fee"); 31 | const minGasToTransferAndStore = ethers.parseEther( 32 | process.env.MIN_GAS_TO_TRANSFER_AND_STORE as string 33 | ); 34 | if (!minGasToTransferAndStore) 35 | throw new Error("Please set minGasToTransferAndStore"); 36 | const singleGuardianPrice = ethers.parseEther( 37 | process.env.SINGLE_GUARDIAN_PRICE as string 38 | ); 39 | if (!singleGuardianPrice) throw new Error("Please set singleGuardianPrice"); 40 | const influentialWerewolfIpfsContractUri = 41 | process.env.INFLUENTIAL_WEREWOLF_IPFS_CONTRACT_URI; 42 | if (!influentialWerewolfIpfsContractUri) 43 | throw new Error("Please set influentialWerewolfIpfsContractUri"); 44 | const influentialWerewolfIpfsBaseUri = 45 | process.env.INFLUENTIAL_WEREWOLF_IPFS_BASE_URI; 46 | if (!influentialWerewolfIpfsBaseUri) 47 | throw new Error("Please set influentialWerewolfIpfsBaseUri"); 48 | 49 | // Initialize the safeWallet. 50 | const proxyAdminWallet = new Wallet( 51 | `${process.env.PROXY_ADMIN_WALLET_PK}`, 52 | provider 53 | ); 54 | console.log("proxyAdminWallet address: ", await proxyAdminWallet.getAddress()); 55 | 56 | const contractAdminWallet = new Wallet( 57 | `${process.env.CONTRACT_ADMIN_WALLET_PK}`, 58 | provider 59 | ); 60 | console.log("contractAdminWallet address: ", await contractAdminWallet.getAddress()); 61 | 62 | // Initialize deployers 63 | const proxyDeployer = new Deployer(hre, proxyAdminWallet); 64 | const contractDeployer = new Deployer(hre, contractAdminWallet); 65 | 66 | // Deploy the influential werewolf contract 67 | const influentialWerewolfArtifact = await contractDeployer.loadArtifact( 68 | "contracts/guardians/InfluentialWerewolfV1.sol:InfluentialWerewolfV1" 69 | ); 70 | const influentialWerewolfConstArgs = []; 71 | const influentialWerewolfContract = await contractDeployer.deploy( 72 | influentialWerewolfArtifact, 73 | influentialWerewolfConstArgs 74 | ); 75 | console.log( 76 | "args: " + 77 | influentialWerewolfContract.interface.encodeDeploy( 78 | influentialWerewolfConstArgs 79 | ) 80 | ); 81 | console.log( 82 | `${influentialWerewolfArtifact.contractName} was deployed to ${await influentialWerewolfContract.getAddress()}` 83 | ); 84 | 85 | const verifyImpl = await hre.run("verify:verify", { 86 | address: await influentialWerewolfContract.getAddress(), 87 | constructorArguments: influentialWerewolfConstArgs 88 | }); 89 | 90 | console.log("Verification res: ", verifyImpl); 91 | 92 | // Deploy the transparent proxy 93 | const transparentProxyConstArgs = [ 94 | await influentialWerewolfContract.getAddress(), 95 | proxyAdminContractAddress, 96 | "0x" 97 | ]; 98 | const transparentUpgradeableProxyFactory = new ContractFactory( 99 | TransparentUpgradeableProxy.abi, 100 | TransparentUpgradeableProxy.bytecode, 101 | proxyAdminWallet 102 | ); 103 | const transparentProxyContract = 104 | await transparentUpgradeableProxyFactory.deploy( 105 | await influentialWerewolfContract.getAddress(), 106 | proxyAdminContractAddress, 107 | "0x" 108 | ); 109 | await transparentProxyContract.waitForDeployment(); 110 | console.log( 111 | "transparentUpgradeableProxy deployed at:", 112 | await transparentProxyContract.getAddress() 113 | ); 114 | 115 | const verifyProxy = await hre.run("verify:verify", { 116 | address: await transparentProxyContract.getAddress(), 117 | constructorArguments: transparentProxyConstArgs, 118 | }); 119 | 120 | console.log("Verification res: ", verifyProxy); 121 | 122 | 123 | // Initializing InfluentialWerewolfV1 contract through proxy 124 | const NY_JSON = require("../../artifacts-zk/contracts/guardians/InfluentialWerewolfV1.sol/InfluentialWerewolfV1.json"); 125 | const NY_ABI = NY_JSON.abi; 126 | 127 | const nyContract = new Contract( 128 | await transparentProxyContract.getAddress(), 129 | NY_ABI, 130 | contractAdminWallet._signerL2() 131 | ); 132 | 133 | const initializeMpTx = await nyContract.initialize( 134 | layerzeroZkSyncEndpoint, 135 | safeAddress, 136 | crosschainTransferFee, 137 | minGasToTransferAndStore, 138 | singleGuardianPrice, 139 | influentialWerewolfIpfsContractUri, 140 | influentialWerewolfIpfsBaseUri 141 | ); 142 | await initializeMpTx.wait(); 143 | console.log( 144 | "InfluentialWerewolfV1 initialization response: ", 145 | initializeMpTx 146 | ); 147 | } 148 | -------------------------------------------------------------------------------- /contracts/proxy/transparent/TransparentUpgradeableProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // OpenZeppelin Contracts (last updated v4.7.0) (proxy/transparent/TransparentUpgradeableProxy.sol) 3 | 4 | pragma solidity 0.8.18; 5 | 6 | import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; 7 | 8 | /** 9 | * @dev This contract implements a proxy that is upgradeable by an admin. 10 | * 11 | * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector 12 | * clashing], which can potentially be used in an attack, this contract uses the 13 | * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two 14 | * things that go hand in hand: 15 | * 16 | * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if 17 | * that call matches one of the admin functions exposed by the proxy itself. 18 | * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the 19 | * implementation. If the admin tries to call a function on the implementation it will fail with an error that says 20 | * "admin cannot fallback to proxy target". 21 | * 22 | * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing 23 | * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due 24 | * to sudden errors when trying to call a function from the proxy implementation. 25 | * 26 | * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, 27 | * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy. 28 | */ 29 | contract TransparentUpgradeableProxy is ERC1967Proxy { 30 | /** 31 | * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and 32 | * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}. 33 | */ 34 | constructor( 35 | address _logic, 36 | address admin_, 37 | bytes memory _data 38 | ) payable ERC1967Proxy(_logic, _data) { 39 | _changeAdmin(admin_); 40 | } 41 | 42 | /** 43 | * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin. 44 | */ 45 | modifier ifAdmin() { 46 | if (msg.sender == _getAdmin()) { 47 | _; 48 | } else { 49 | _fallback(); 50 | } 51 | } 52 | 53 | /** 54 | * @dev Returns the current admin. 55 | * 56 | * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. 57 | * 58 | * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the 59 | * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. 60 | * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103` 61 | */ 62 | function admin() external payable ifAdmin returns (address admin_) { 63 | _requireZeroValue(); 64 | admin_ = _getAdmin(); 65 | } 66 | 67 | /** 68 | * @dev Returns the current implementation. 69 | * 70 | * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. 71 | * 72 | * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the 73 | * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. 74 | * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` 75 | */ 76 | function implementation() 77 | external 78 | payable 79 | ifAdmin 80 | returns (address implementation_) 81 | { 82 | _requireZeroValue(); 83 | implementation_ = _implementation(); 84 | } 85 | 86 | /** 87 | * @dev Changes the admin of the proxy. 88 | * 89 | * Emits an {AdminChanged} event. 90 | * 91 | * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}. 92 | */ 93 | function changeAdmin(address newAdmin) external payable virtual ifAdmin { 94 | _requireZeroValue(); 95 | _changeAdmin(newAdmin); 96 | } 97 | 98 | /** 99 | * @dev Upgrade the implementation of the proxy. 100 | * 101 | * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}. 102 | */ 103 | function upgradeTo(address newImplementation) external payable ifAdmin { 104 | _requireZeroValue(); 105 | _upgradeToAndCall(newImplementation, bytes(""), false); 106 | } 107 | 108 | /** 109 | * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified 110 | * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the 111 | * proxied contract. 112 | * 113 | * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}. 114 | */ 115 | function upgradeToAndCall( 116 | address newImplementation, 117 | bytes calldata data 118 | ) external payable ifAdmin { 119 | _upgradeToAndCall(newImplementation, data, true); 120 | } 121 | 122 | /** 123 | * @dev Returns the current admin. 124 | */ 125 | function _admin() internal view virtual returns (address) { 126 | return _getAdmin(); 127 | } 128 | 129 | /** 130 | * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}. 131 | */ 132 | function _beforeFallback() internal virtual override { 133 | require( 134 | msg.sender != _getAdmin(), 135 | "TransparentUpgradeableProxy: admin cannot fallback to proxy target" 136 | ); 137 | super._beforeFallback(); 138 | } 139 | 140 | /** 141 | * @dev To keep this contract fully transparent, all `ifAdmin` functions must be payable. This helper is here to 142 | * emulate some proxy functions being non-payable while still allowing value to pass through. 143 | */ 144 | function _requireZeroValue() private { 145 | require(msg.value == 0); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /interfaces/external/layer-zero/ILayerZeroEndpoint.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | import "./ILayerZeroUserApplicationConfig.sol"; 6 | 7 | interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig { 8 | // @notice send a LayerZero message to the specified address at a LayerZero endpoint. 9 | // @param _dstChainId - the destination chain identifier 10 | // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains 11 | // @param _payload - a custom bytes payload to send to the destination contract 12 | // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address 13 | // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction 14 | // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination 15 | function send( 16 | uint16 _dstChainId, 17 | bytes calldata _destination, 18 | bytes calldata _payload, 19 | address payable _refundAddress, 20 | address _zroPaymentAddress, 21 | bytes calldata _adapterParams 22 | ) external payable; 23 | 24 | // @notice used by the messaging library to publish verified payload 25 | // @param _srcChainId - the source chain identifier 26 | // @param _srcAddress - the source contract (as bytes) at the source chain 27 | // @param _dstAddress - the address on destination chain 28 | // @param _nonce - the unbound message ordering nonce 29 | // @param _gasLimit - the gas limit for external contract execution 30 | // @param _payload - verified payload to send to the destination contract 31 | function receivePayload( 32 | uint16 _srcChainId, 33 | bytes calldata _srcAddress, 34 | address _dstAddress, 35 | uint64 _nonce, 36 | uint256 _gasLimit, 37 | bytes calldata _payload 38 | ) external; 39 | 40 | // @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain 41 | // @param _srcChainId - the source chain identifier 42 | // @param _srcAddress - the source chain contract address 43 | function getInboundNonce( 44 | uint16 _srcChainId, 45 | bytes calldata _srcAddress 46 | ) external view returns (uint64); 47 | 48 | // @notice get the outboundNonce from this source chain which, consequently, is always an EVM 49 | // @param _srcAddress - the source chain contract address 50 | function getOutboundNonce( 51 | uint16 _dstChainId, 52 | address _srcAddress 53 | ) external view returns (uint64); 54 | 55 | // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery 56 | // @param _dstChainId - the destination chain identifier 57 | // @param _userApplication - the user app address on this EVM chain 58 | // @param _payload - the custom message to send over LayerZero 59 | // @param _payInZRO - if false, user app pays the protocol fee in native token 60 | // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain 61 | function estimateFees( 62 | uint16 _dstChainId, 63 | address _userApplication, 64 | bytes calldata _payload, 65 | bool _payInZRO, 66 | bytes calldata _adapterParam 67 | ) external view returns (uint256 nativeFee, uint256 zroFee); 68 | 69 | // @notice get this Endpoint's immutable source identifier 70 | function getChainId() external view returns (uint16); 71 | 72 | // @notice the interface to retry failed message on this Endpoint destination 73 | // @param _srcChainId - the source chain identifier 74 | // @param _srcAddress - the source chain contract address 75 | // @param _payload - the payload to be retried 76 | function retryPayload( 77 | uint16 _srcChainId, 78 | bytes calldata _srcAddress, 79 | bytes calldata _payload 80 | ) external; 81 | 82 | // @notice query if any STORED payload (message blocking) at the endpoint. 83 | // @param _srcChainId - the source chain identifier 84 | // @param _srcAddress - the source chain contract address 85 | function hasStoredPayload( 86 | uint16 _srcChainId, 87 | bytes calldata _srcAddress 88 | ) external view returns (bool); 89 | 90 | // @notice query if the _libraryAddress is valid for sending msgs. 91 | // @param _userApplication - the user app address on this EVM chain 92 | function getSendLibraryAddress( 93 | address _userApplication 94 | ) external view returns (address); 95 | 96 | // @notice query if the _libraryAddress is valid for receiving msgs. 97 | // @param _userApplication - the user app address on this EVM chain 98 | function getReceiveLibraryAddress( 99 | address _userApplication 100 | ) external view returns (address); 101 | 102 | // @notice query if the non-reentrancy guard for send() is on 103 | // @return true if the guard is on. false otherwise 104 | function isSendingPayload() external view returns (bool); 105 | 106 | // @notice query if the non-reentrancy guard for receive() is on 107 | // @return true if the guard is on. false otherwise 108 | function isReceivingPayload() external view returns (bool); 109 | 110 | // @notice get the configuration of the LayerZero messaging library of the specified version 111 | // @param _version - messaging library version 112 | // @param _chainId - the chainId for the pending config change 113 | // @param _userApplication - the contract address of the user application 114 | // @param _configType - type of configuration. every messaging library has its own convention. 115 | function getConfig( 116 | uint16 _version, 117 | uint16 _chainId, 118 | address _userApplication, 119 | uint256 _configType 120 | ) external view returns (bytes memory); 121 | 122 | // @notice get the send() LayerZero messaging library version 123 | // @param _userApplication - the contract address of the user application 124 | function getSendVersion( 125 | address _userApplication 126 | ) external view returns (uint16); 127 | 128 | // @notice get the lzReceive() LayerZero messaging library version 129 | // @param _userApplication - the contract address of the user application 130 | function getReceiveVersion( 131 | address _userApplication 132 | ) external view returns (uint16); 133 | } 134 | -------------------------------------------------------------------------------- /interfaces/external/layer-zero/ILayerZeroEndpointUpgradeable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.2; 4 | 5 | import "./ILayerZeroUserApplicationConfigUpgradeable.sol"; 6 | 7 | interface ILayerZeroEndpointUpgradeable is 8 | ILayerZeroUserApplicationConfigUpgradeable 9 | { 10 | // @notice send a LayerZero message to the specified address at a LayerZero endpoint. 11 | // @param _dstChainId - the destination chain identifier 12 | // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains 13 | // @param _payload - a custom bytes payload to send to the destination contract 14 | // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address 15 | // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction 16 | // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination 17 | function send( 18 | uint16 _dstChainId, 19 | bytes calldata _destination, 20 | bytes calldata _payload, 21 | address payable _refundAddress, 22 | address _zroPaymentAddress, 23 | bytes calldata _adapterParams 24 | ) external payable; 25 | 26 | // @notice used by the messaging library to publish verified payload 27 | // @param _srcChainId - the source chain identifier 28 | // @param _srcAddress - the source contract (as bytes) at the source chain 29 | // @param _dstAddress - the address on destination chain 30 | // @param _nonce - the unbound message ordering nonce 31 | // @param _gasLimit - the gas limit for external contract execution 32 | // @param _payload - verified payload to send to the destination contract 33 | function receivePayload( 34 | uint16 _srcChainId, 35 | bytes calldata _srcAddress, 36 | address _dstAddress, 37 | uint64 _nonce, 38 | uint _gasLimit, 39 | bytes calldata _payload 40 | ) external; 41 | 42 | // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain 43 | // @param _srcChainId - the source chain identifier 44 | // @param _srcAddress - the source chain contract address 45 | function getInboundNonce( 46 | uint16 _srcChainId, 47 | bytes calldata _srcAddress 48 | ) external view returns (uint64); 49 | 50 | // @notice get the outboundNonce from this source chain which, consequently, is always an EVM 51 | // @param _srcAddress - the source chain contract address 52 | function getOutboundNonce( 53 | uint16 _dstChainId, 54 | address _srcAddress 55 | ) external view returns (uint64); 56 | 57 | // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery 58 | // @param _dstChainId - the destination chain identifier 59 | // @param _userApplication - the user app address on this EVM chain 60 | // @param _payload - the custom message to send over LayerZero 61 | // @param _payInZRO - if false, user app pays the protocol fee in native token 62 | // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain 63 | function estimateFees( 64 | uint16 _dstChainId, 65 | address _userApplication, 66 | bytes calldata _payload, 67 | bool _payInZRO, 68 | bytes calldata _adapterParam 69 | ) external view returns (uint nativeFee, uint zroFee); 70 | 71 | // @notice get this Endpoint's immutable source identifier 72 | function getChainId() external view returns (uint16); 73 | 74 | // @notice the interface to retry failed message on this Endpoint destination 75 | // @param _srcChainId - the source chain identifier 76 | // @param _srcAddress - the source chain contract address 77 | // @param _payload - the payload to be retried 78 | function retryPayload( 79 | uint16 _srcChainId, 80 | bytes calldata _srcAddress, 81 | bytes calldata _payload 82 | ) external; 83 | 84 | // @notice query if any STORED payload (message blocking) at the endpoint. 85 | // @param _srcChainId - the source chain identifier 86 | // @param _srcAddress - the source chain contract address 87 | function hasStoredPayload( 88 | uint16 _srcChainId, 89 | bytes calldata _srcAddress 90 | ) external view returns (bool); 91 | 92 | // @notice query if the _libraryAddress is valid for sending msgs. 93 | // @param _userApplication - the user app address on this EVM chain 94 | function getSendLibraryAddress( 95 | address _userApplication 96 | ) external view returns (address); 97 | 98 | // @notice query if the _libraryAddress is valid for receiving msgs. 99 | // @param _userApplication - the user app address on this EVM chain 100 | function getReceiveLibraryAddress( 101 | address _userApplication 102 | ) external view returns (address); 103 | 104 | // @notice query if the non-reentrancy guard for send() is on 105 | // @return true if the guard is on. false otherwise 106 | function isSendingPayload() external view returns (bool); 107 | 108 | // @notice query if the non-reentrancy guard for receive() is on 109 | // @return true if the guard is on. false otherwise 110 | function isReceivingPayload() external view returns (bool); 111 | 112 | // @notice get the configuration of the LayerZero messaging library of the specified version 113 | // @param _version - messaging library version 114 | // @param _chainId - the chainId for the pending config change 115 | // @param _userApplication - the contract address of the user application 116 | // @param _configType - type of configuration. every messaging library has its own convention. 117 | function getConfig( 118 | uint16 _version, 119 | uint16 _chainId, 120 | address _userApplication, 121 | uint _configType 122 | ) external view returns (bytes memory); 123 | 124 | // @notice get the send() LayerZero messaging library version 125 | // @param _userApplication - the contract address of the user application 126 | function getSendVersion( 127 | address _userApplication 128 | ) external view returns (uint16); 129 | 130 | // @notice get the lzReceive() LayerZero messaging library version 131 | // @param _userApplication - the contract address of the user application 132 | function getReceiveVersion( 133 | address _userApplication 134 | ) external view returns (uint16); 135 | } 136 | -------------------------------------------------------------------------------- /contracts/guardians/ReformistSphinxV1.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.18; 3 | 4 | import "../citizenid/CitizenIDV1.sol"; 5 | import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; 6 | import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; 7 | import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; 8 | import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; 9 | import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721RoyaltyUpgradeable.sol"; 10 | import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol"; 11 | import "@openzeppelin/contracts-upgradeable/utils/Base64Upgradeable.sol"; 12 | import "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol"; 13 | import "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol"; 14 | 15 | /// @title ReformistSphinx NFT contract 16 | /// @author Tevaera Labs 17 | /// @notice Allows users to mint the guardian NFT of ReformistSphinx 18 | /// @dev It extends ERC721 and ERC2981 standards 19 | contract ReformistSphinxV1 is 20 | ERC721RoyaltyUpgradeable, 21 | ERC721URIStorageUpgradeable, 22 | ERC721EnumerableUpgradeable, 23 | OwnableUpgradeable, 24 | PausableUpgradeable, 25 | ReentrancyGuardUpgradeable 26 | { 27 | using CountersUpgradeable for CountersUpgradeable.Counter; 28 | using StringsUpgradeable for uint256; 29 | 30 | CitizenIDV1 private citizenIdContract; 31 | CountersUpgradeable.Counter private tokenIdCounter; 32 | 33 | modifier isNotBlacklisted() { 34 | require( 35 | !citizenIdContract.blacklisted(msg.sender), 36 | "Tevan Blacklisted!" 37 | ); 38 | _; 39 | } 40 | 41 | modifier isTevan() { 42 | require(citizenIdContract.balanceOf(msg.sender) > 0, "Not a Tevan"); 43 | _; 44 | } 45 | 46 | string public tokenImageUri; 47 | 48 | mapping(address => bool) private addressToHasMintedMap; 49 | 50 | /// @dev Initializes the upgradable contract 51 | /// @param _citizenIdContract the citizen id contract address 52 | /// @param _tokenImageUri the token image uri 53 | function initialize( 54 | CitizenIDV1 _citizenIdContract, 55 | string calldata _tokenImageUri 56 | ) external initializer { 57 | __ERC721_init("ReformistSphinx", "SPHINX"); 58 | __ERC721Enumerable_init(); 59 | __ERC721Royalty_init(); 60 | __Ownable_init(); 61 | __Pausable_init(); 62 | __ReentrancyGuard_init(); 63 | 64 | citizenIdContract = _citizenIdContract; 65 | tokenImageUri = _tokenImageUri; 66 | 67 | // increament the counter 68 | tokenIdCounter.increment(); 69 | 70 | // set default royalty to 5% 71 | _setDefaultRoyalty(msg.sender, 500); 72 | } 73 | 74 | /// @dev Mints Guardian NFT 75 | function mint() 76 | external 77 | isTevan 78 | isNotBlacklisted 79 | whenNotPaused 80 | nonReentrant 81 | { 82 | // make sure caller has not already minted 83 | require(addressToHasMintedMap[msg.sender] == false, "already minted"); 84 | 85 | // get the token id & update the counter 86 | uint256 tokenId = tokenIdCounter.current(); 87 | tokenIdCounter.increment(); 88 | 89 | // mint the guardian nft 90 | _mint(msg.sender, tokenId); 91 | 92 | // mark address as minted 93 | addressToHasMintedMap[msg.sender] = true; 94 | 95 | // set the token uri 96 | _setTokenURI(tokenId, getTokenURI(tokenId)); 97 | } 98 | 99 | /// @dev Sets the token base uri 100 | /// @param _tokenImageUri the token base uri 101 | function setTokenImageUri( 102 | string calldata _tokenImageUri 103 | ) external onlyOwner whenNotPaused { 104 | tokenImageUri = _tokenImageUri; 105 | } 106 | 107 | // ----- system default functions ----- 108 | 109 | /// @dev Allows owner to pause sale if active 110 | function pause() public onlyOwner whenNotPaused { 111 | _pause(); 112 | } 113 | 114 | /// @dev Allows owner to activate sale 115 | function unpause() public onlyOwner whenPaused { 116 | _unpause(); 117 | } 118 | 119 | function _burn( 120 | uint256 tokenId 121 | ) 122 | internal 123 | override( 124 | ERC721Upgradeable, 125 | ERC721RoyaltyUpgradeable, 126 | ERC721URIStorageUpgradeable 127 | ) 128 | { 129 | super._burn(tokenId); 130 | } 131 | 132 | function _beforeTokenTransfer( 133 | address from, 134 | address to, 135 | uint256 tokenId, 136 | uint256 batchSize 137 | ) 138 | internal 139 | override(ERC721Upgradeable, ERC721EnumerableUpgradeable) 140 | whenNotPaused 141 | { 142 | super._beforeTokenTransfer(from, to, tokenId, batchSize); 143 | } 144 | 145 | function getTokenURI( 146 | uint256 tokenId 147 | ) internal view returns (string memory) { 148 | bytes memory dataURI = abi.encodePacked( 149 | "{", 150 | '"name": "Reformist Sphinx #', 151 | tokenId.toString(), 152 | '",', 153 | '"description": "The Reformist Guardian, who is seen as a symbol of change & wisdom. Sphinxes keep a track of all past events and help people escape to a new gamified world to experience their imaginations.",', 154 | '"external_url": "https://tevaera.com",', 155 | '"image": "', 156 | tokenImageUri, 157 | '",', 158 | '"attributes": [{"trait_type":"Guardian", "value": "Sphinx"}, {"trait_type":"Skin", "value": "Brown"}]', 159 | "}" 160 | ); 161 | 162 | return 163 | string( 164 | abi.encodePacked( 165 | "data:application/json;base64,", 166 | Base64Upgradeable.encode(dataURI) 167 | ) 168 | ); 169 | } 170 | 171 | function supportsInterface( 172 | bytes4 interfaceId 173 | ) 174 | public 175 | view 176 | override( 177 | ERC721RoyaltyUpgradeable, 178 | ERC721EnumerableUpgradeable, 179 | ERC721URIStorageUpgradeable 180 | ) 181 | returns (bool) 182 | { 183 | return super.supportsInterface(interfaceId); 184 | } 185 | 186 | function tokenURI( 187 | uint256 tokenId 188 | ) 189 | public 190 | view 191 | override(ERC721Upgradeable, ERC721URIStorageUpgradeable) 192 | returns (string memory) 193 | { 194 | return super.tokenURI(tokenId); 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /contracts/guardians/crosschain/NomadicYetiV1.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.18; 3 | 4 | import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; 5 | import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; 6 | import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; 7 | import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; 8 | import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721RoyaltyUpgradeable.sol"; 9 | import "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol"; 10 | 11 | import "../../external/layer-zero/ONFT721CoreUpgradeable.sol"; 12 | 13 | /// @title NomadicYeti NFT contract 14 | /// @author Tevaera Labs 15 | /// @notice Allows users to mint the guardian ONFT of NomadicYeti 16 | /// @dev It extends ERC721 and ERC2981 standards 17 | contract NomadicYetiV1 is 18 | ERC721RoyaltyUpgradeable, 19 | ERC721EnumerableUpgradeable, 20 | PausableUpgradeable, 21 | ReentrancyGuardUpgradeable, 22 | ONFT721CoreUpgradeable 23 | { 24 | using CountersUpgradeable for CountersUpgradeable.Counter; 25 | 26 | /// @dev the safe address 27 | address payable private safeAddress; 28 | 29 | CountersUpgradeable.Counter private tokenIdCounter; 30 | 31 | /// @dev the token base uri 32 | string private tokenBaseUri; 33 | 34 | /// @dev Contract level metadata. 35 | string public contractURI; 36 | 37 | function initialize( 38 | address _lzEndpoint, 39 | address _safeAddress, 40 | uint256 _crosschainTransferFee, 41 | uint256 _minGasToTransferAndStore, 42 | string calldata _contractUri, 43 | string calldata _tokenBaseUri 44 | ) external initializer { 45 | __ERC721_init("Nomadic Yeti", "YETI"); 46 | __ERC721Enumerable_init(); 47 | __ERC721Royalty_init(); 48 | __Ownable_init_unchained(); 49 | __ONFT721CoreUpgradeable_init( 50 | _minGasToTransferAndStore, 51 | _lzEndpoint, 52 | _crosschainTransferFee, 53 | _safeAddress 54 | ); 55 | __Pausable_init(); 56 | __ReentrancyGuard_init(); 57 | 58 | // set contract uri which contains contract level metadata 59 | contractURI = _contractUri; 60 | // set safe address 61 | safeAddress = payable(_safeAddress); 62 | // set token base uri 63 | tokenBaseUri = _tokenBaseUri; 64 | 65 | // set default royalty to 2.5% 66 | _setDefaultRoyalty(_safeAddress, 250); 67 | } 68 | 69 | /// @dev Lets a contract admin set the URI for the contract-level metadata. 70 | function setContractURI(string calldata _uri) external onlyOwner { 71 | contractURI = _uri; 72 | } 73 | 74 | /// @dev Sets the token base uri 75 | /// @param _tokenBaseUri the token base uri 76 | function setTokenBaseUri( 77 | string calldata _tokenBaseUri 78 | ) external onlyOwner whenNotPaused { 79 | tokenBaseUri = _tokenBaseUri; 80 | } 81 | 82 | /// @dev Allows owner to update the safe wallet address 83 | /// @param _safeAddress the safe wallet address 84 | function updateSafeAddress( 85 | address payable _safeAddress 86 | ) external onlyOwner { 87 | require(_safeAddress != address(0), "Invalid address!"); 88 | safeAddress = _safeAddress; 89 | } 90 | 91 | /// @dev Withdraws the funds 92 | function withdraw(address token, uint256 amount) external onlyOwner { 93 | if (token == address(0)) { 94 | // Withdraw Ether 95 | require( 96 | address(this).balance >= amount, 97 | "Insufficient Ether balance" 98 | ); 99 | // Transfer Ether to the owner 100 | (bool success, ) = payable(msg.sender).call{value: amount}(""); 101 | require(success, "Ether transfer failed"); 102 | } else { 103 | // Withdraw ERC-20 tokens 104 | IERC20Upgradeable erc20Token = IERC20Upgradeable(token); 105 | uint256 contractBalance = erc20Token.balanceOf(address(this)); 106 | require(contractBalance >= amount, "Insufficient token balance"); 107 | // Transfer ERC-20 tokens to the owner 108 | require( 109 | erc20Token.transfer(msg.sender, amount), 110 | "Token transfer failed" 111 | ); 112 | } 113 | } 114 | 115 | /// @dev Debits a token from user's account to transfer it to another chain 116 | function _debitFrom( 117 | address _from, 118 | uint16, 119 | bytes memory, 120 | uint _tokenId 121 | ) internal virtual override { 122 | require( 123 | _from == _msgSender(), 124 | "ProxyONFT721: owner is not send caller" 125 | ); 126 | 127 | _burn(_tokenId); 128 | } 129 | 130 | /// @dev Credits a token to user's account received from another chain 131 | function _creditTo( 132 | uint16, 133 | address _toAddress, 134 | uint _tokenId 135 | ) internal virtual override { 136 | _safeMint(_toAddress, _tokenId); 137 | } 138 | 139 | // ----- system default functions ----- 140 | 141 | /// @dev Allows owner to pause sale if active 142 | function pause() public onlyOwner whenNotPaused { 143 | _pause(); 144 | } 145 | 146 | /// @dev Allows owner to activate sale 147 | function unpause() public onlyOwner whenPaused { 148 | _unpause(); 149 | } 150 | 151 | function _burn( 152 | uint256 tokenId 153 | ) internal override(ERC721Upgradeable, ERC721RoyaltyUpgradeable) { 154 | super._burn(tokenId); 155 | } 156 | 157 | function _beforeTokenTransfer( 158 | address from, 159 | address to, 160 | uint256 tokenId, 161 | uint256 batchSize 162 | ) 163 | internal 164 | override(ERC721Upgradeable, ERC721EnumerableUpgradeable) 165 | whenNotPaused 166 | { 167 | super._beforeTokenTransfer(from, to, tokenId, batchSize); 168 | } 169 | 170 | function supportsInterface( 171 | bytes4 interfaceId 172 | ) 173 | public 174 | view 175 | override( 176 | ERC721RoyaltyUpgradeable, 177 | ERC721EnumerableUpgradeable, 178 | ONFT721CoreUpgradeable 179 | ) 180 | returns (bool) 181 | { 182 | return super.supportsInterface(interfaceId); 183 | } 184 | 185 | function _baseURI() 186 | internal 187 | view 188 | override(ERC721Upgradeable) 189 | returns (string memory) 190 | { 191 | return tokenBaseUri; 192 | } 193 | 194 | function tokenURI( 195 | uint256 tokenId 196 | ) public view override(ERC721Upgradeable) returns (string memory) { 197 | return super.tokenURI(tokenId); 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /contracts/guardians/crosschain/BalancerDragonV1.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.18; 3 | 4 | import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; 5 | import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; 6 | import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; 7 | import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; 8 | import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721RoyaltyUpgradeable.sol"; 9 | import "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol"; 10 | 11 | import "../../external/layer-zero/ONFT721CoreUpgradeable.sol"; 12 | 13 | /// @title BalancerDragon NFT contract 14 | /// @author Tevaera Labs 15 | /// @notice Allows users to mint the guardian ONFT of BalancerDragon 16 | /// @dev It extends ERC721 and ERC2981 standards 17 | contract BalancerDragonV1 is 18 | ERC721RoyaltyUpgradeable, 19 | ERC721EnumerableUpgradeable, 20 | PausableUpgradeable, 21 | ReentrancyGuardUpgradeable, 22 | ONFT721CoreUpgradeable 23 | { 24 | using CountersUpgradeable for CountersUpgradeable.Counter; 25 | 26 | /// @dev the safe address 27 | address payable private safeAddress; 28 | 29 | CountersUpgradeable.Counter private tokenIdCounter; 30 | 31 | /// @dev the token base uri 32 | string private tokenBaseUri; 33 | 34 | /// @dev Contract level metadata. 35 | string public contractURI; 36 | 37 | function initialize( 38 | address _lzEndpoint, 39 | address _safeAddress, 40 | uint256 _crosschainTransferFee, 41 | uint256 _minGasToTransferAndStore, 42 | string calldata _contractUri, 43 | string calldata _tokenBaseUri 44 | ) external initializer { 45 | __ERC721_init("Balancer Dragon", "DRAGON"); 46 | __ERC721Enumerable_init(); 47 | __ERC721Royalty_init(); 48 | __Ownable_init_unchained(); 49 | __ONFT721CoreUpgradeable_init( 50 | _minGasToTransferAndStore, 51 | _lzEndpoint, 52 | _crosschainTransferFee, 53 | _safeAddress 54 | ); 55 | __Pausable_init(); 56 | __ReentrancyGuard_init(); 57 | 58 | // set contract uri which contains contract level metadata 59 | contractURI = _contractUri; 60 | // set safe address 61 | safeAddress = payable(_safeAddress); 62 | // set token base uri 63 | tokenBaseUri = _tokenBaseUri; 64 | 65 | // set default royalty to 2.5% 66 | _setDefaultRoyalty(_safeAddress, 250); 67 | } 68 | 69 | /// @dev Lets a contract admin set the URI for the contract-level metadata. 70 | function setContractURI(string calldata _uri) external onlyOwner { 71 | contractURI = _uri; 72 | } 73 | 74 | /// @dev Sets the token base uri 75 | /// @param _tokenBaseUri the token base uri 76 | function setTokenBaseUri( 77 | string calldata _tokenBaseUri 78 | ) external onlyOwner whenNotPaused { 79 | tokenBaseUri = _tokenBaseUri; 80 | } 81 | 82 | /// @dev Allows owner to update the safe wallet address 83 | /// @param _safeAddress the safe wallet address 84 | function updateSafeAddress( 85 | address payable _safeAddress 86 | ) external onlyOwner { 87 | require(_safeAddress != address(0), "Invalid address!"); 88 | safeAddress = _safeAddress; 89 | } 90 | 91 | /// @dev Withdraws the funds 92 | function withdraw(address token, uint256 amount) external onlyOwner { 93 | if (token == address(0)) { 94 | // Withdraw Ether 95 | require( 96 | address(this).balance >= amount, 97 | "Insufficient Ether balance" 98 | ); 99 | // Transfer Ether to the owner 100 | (bool success, ) = payable(msg.sender).call{value: amount}(""); 101 | require(success, "Ether transfer failed"); 102 | } else { 103 | // Withdraw ERC-20 tokens 104 | IERC20Upgradeable erc20Token = IERC20Upgradeable(token); 105 | uint256 contractBalance = erc20Token.balanceOf(address(this)); 106 | require(contractBalance >= amount, "Insufficient token balance"); 107 | // Transfer ERC-20 tokens to the owner 108 | require( 109 | erc20Token.transfer(msg.sender, amount), 110 | "Token transfer failed" 111 | ); 112 | } 113 | } 114 | 115 | /// @dev Debits a token from user's account to transfer it to another chain 116 | function _debitFrom( 117 | address _from, 118 | uint16, 119 | bytes memory, 120 | uint _tokenId 121 | ) internal virtual override { 122 | require( 123 | _from == _msgSender(), 124 | "ProxyONFT721: owner is not send caller" 125 | ); 126 | 127 | _burn(_tokenId); 128 | } 129 | 130 | /// @dev Credits a token to user's account received from another chain 131 | function _creditTo( 132 | uint16, 133 | address _toAddress, 134 | uint _tokenId 135 | ) internal virtual override { 136 | _safeMint(_toAddress, _tokenId); 137 | } 138 | 139 | // ----- system default functions ----- 140 | 141 | /// @dev Allows owner to pause sale if active 142 | function pause() public onlyOwner whenNotPaused { 143 | _pause(); 144 | } 145 | 146 | /// @dev Allows owner to activate sale 147 | function unpause() public onlyOwner whenPaused { 148 | _unpause(); 149 | } 150 | 151 | function _burn( 152 | uint256 tokenId 153 | ) internal override(ERC721Upgradeable, ERC721RoyaltyUpgradeable) { 154 | super._burn(tokenId); 155 | } 156 | 157 | function _beforeTokenTransfer( 158 | address from, 159 | address to, 160 | uint256 tokenId, 161 | uint256 batchSize 162 | ) 163 | internal 164 | override(ERC721Upgradeable, ERC721EnumerableUpgradeable) 165 | whenNotPaused 166 | { 167 | super._beforeTokenTransfer(from, to, tokenId, batchSize); 168 | } 169 | 170 | function supportsInterface( 171 | bytes4 interfaceId 172 | ) 173 | public 174 | view 175 | override( 176 | ERC721RoyaltyUpgradeable, 177 | ERC721EnumerableUpgradeable, 178 | ONFT721CoreUpgradeable 179 | ) 180 | returns (bool) 181 | { 182 | return super.supportsInterface(interfaceId); 183 | } 184 | 185 | function _baseURI() 186 | internal 187 | view 188 | override(ERC721Upgradeable) 189 | returns (string memory) 190 | { 191 | return tokenBaseUri; 192 | } 193 | 194 | function tokenURI( 195 | uint256 tokenId 196 | ) public view override(ERC721Upgradeable) returns (string memory) { 197 | return super.tokenURI(tokenId); 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /contracts/guardians/crosschain/SimplifierKrakenV1.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.18; 3 | 4 | import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; 5 | import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; 6 | import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; 7 | import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; 8 | import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721RoyaltyUpgradeable.sol"; 9 | import "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol"; 10 | 11 | import "../../external/layer-zero/ONFT721CoreUpgradeable.sol"; 12 | 13 | /// @title SimplifierKraken NFT contract 14 | /// @author Tevaera Labs 15 | /// @notice Allows users to mint the guardian ONFT of SimplifierKraken 16 | /// @dev It extends ERC721 and ERC2981 standards 17 | contract SimplifierKrakenV1 is 18 | ERC721RoyaltyUpgradeable, 19 | ERC721EnumerableUpgradeable, 20 | PausableUpgradeable, 21 | ReentrancyGuardUpgradeable, 22 | ONFT721CoreUpgradeable 23 | { 24 | using CountersUpgradeable for CountersUpgradeable.Counter; 25 | 26 | /// @dev the safe address 27 | address payable private safeAddress; 28 | 29 | CountersUpgradeable.Counter private tokenIdCounter; 30 | 31 | /// @dev the token base uri 32 | string private tokenBaseUri; 33 | 34 | /// @dev Contract level metadata. 35 | string public contractURI; 36 | 37 | function initialize( 38 | address _lzEndpoint, 39 | address _safeAddress, 40 | uint256 _crosschainTransferFee, 41 | uint256 _minGasToTransferAndStore, 42 | string calldata _contractUri, 43 | string calldata _tokenBaseUri 44 | ) external initializer { 45 | __ERC721_init("Simplifier Kraken", "KRAKEN"); 46 | __ERC721Enumerable_init(); 47 | __ERC721Royalty_init(); 48 | __Ownable_init_unchained(); 49 | __ONFT721CoreUpgradeable_init( 50 | _minGasToTransferAndStore, 51 | _lzEndpoint, 52 | _crosschainTransferFee, 53 | _safeAddress 54 | ); 55 | __Pausable_init(); 56 | __ReentrancyGuard_init(); 57 | 58 | // set contract uri which contains contract level metadata 59 | contractURI = _contractUri; 60 | // set safe address 61 | safeAddress = payable(_safeAddress); 62 | // set token base uri 63 | tokenBaseUri = _tokenBaseUri; 64 | 65 | // set default royalty to 2.5% 66 | _setDefaultRoyalty(_safeAddress, 250); 67 | } 68 | 69 | /// @dev Lets a contract admin set the URI for the contract-level metadata. 70 | function setContractURI(string calldata _uri) external onlyOwner { 71 | contractURI = _uri; 72 | } 73 | 74 | /// @dev Sets the token base uri 75 | /// @param _tokenBaseUri the token base uri 76 | function setTokenBaseUri( 77 | string calldata _tokenBaseUri 78 | ) external onlyOwner whenNotPaused { 79 | tokenBaseUri = _tokenBaseUri; 80 | } 81 | 82 | /// @dev Allows owner to update the safe wallet address 83 | /// @param _safeAddress the safe wallet address 84 | function updateSafeAddress( 85 | address payable _safeAddress 86 | ) external onlyOwner { 87 | require(_safeAddress != address(0), "Invalid address!"); 88 | safeAddress = _safeAddress; 89 | } 90 | 91 | /// @dev Withdraws the funds 92 | function withdraw(address token, uint256 amount) external onlyOwner { 93 | if (token == address(0)) { 94 | // Withdraw Ether 95 | require( 96 | address(this).balance >= amount, 97 | "Insufficient Ether balance" 98 | ); 99 | // Transfer Ether to the owner 100 | (bool success, ) = payable(msg.sender).call{value: amount}(""); 101 | require(success, "Ether transfer failed"); 102 | } else { 103 | // Withdraw ERC-20 tokens 104 | IERC20Upgradeable erc20Token = IERC20Upgradeable(token); 105 | uint256 contractBalance = erc20Token.balanceOf(address(this)); 106 | require(contractBalance >= amount, "Insufficient token balance"); 107 | // Transfer ERC-20 tokens to the owner 108 | require( 109 | erc20Token.transfer(msg.sender, amount), 110 | "Token transfer failed" 111 | ); 112 | } 113 | } 114 | 115 | /// @dev Debits a token from user's account to transfer it to another chain 116 | function _debitFrom( 117 | address _from, 118 | uint16, 119 | bytes memory, 120 | uint _tokenId 121 | ) internal virtual override { 122 | require( 123 | _from == _msgSender(), 124 | "ProxyONFT721: owner is not send caller" 125 | ); 126 | 127 | _burn(_tokenId); 128 | } 129 | 130 | /// @dev Credits a token to user's account received from another chain 131 | function _creditTo( 132 | uint16, 133 | address _toAddress, 134 | uint _tokenId 135 | ) internal virtual override { 136 | _safeMint(_toAddress, _tokenId); 137 | } 138 | 139 | // ----- system default functions ----- 140 | 141 | /// @dev Allows owner to pause sale if active 142 | function pause() public onlyOwner whenNotPaused { 143 | _pause(); 144 | } 145 | 146 | /// @dev Allows owner to activate sale 147 | function unpause() public onlyOwner whenPaused { 148 | _unpause(); 149 | } 150 | 151 | function _burn( 152 | uint256 tokenId 153 | ) internal override(ERC721Upgradeable, ERC721RoyaltyUpgradeable) { 154 | super._burn(tokenId); 155 | } 156 | 157 | function _beforeTokenTransfer( 158 | address from, 159 | address to, 160 | uint256 tokenId, 161 | uint256 batchSize 162 | ) 163 | internal 164 | override(ERC721Upgradeable, ERC721EnumerableUpgradeable) 165 | whenNotPaused 166 | { 167 | super._beforeTokenTransfer(from, to, tokenId, batchSize); 168 | } 169 | 170 | function supportsInterface( 171 | bytes4 interfaceId 172 | ) 173 | public 174 | view 175 | override( 176 | ERC721RoyaltyUpgradeable, 177 | ERC721EnumerableUpgradeable, 178 | ONFT721CoreUpgradeable 179 | ) 180 | returns (bool) 181 | { 182 | return super.supportsInterface(interfaceId); 183 | } 184 | 185 | function _baseURI() 186 | internal 187 | view 188 | override(ERC721Upgradeable) 189 | returns (string memory) 190 | { 191 | return tokenBaseUri; 192 | } 193 | 194 | function tokenURI( 195 | uint256 tokenId 196 | ) public view override(ERC721Upgradeable) returns (string memory) { 197 | return super.tokenURI(tokenId); 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /contracts/guardians/crosschain/InnovativeUnicornV1.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.18; 3 | 4 | import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; 5 | import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; 6 | import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; 7 | import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; 8 | import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721RoyaltyUpgradeable.sol"; 9 | import "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol"; 10 | 11 | import "../../external/layer-zero/ONFT721CoreUpgradeable.sol"; 12 | 13 | /// @title InnovativeUnicorn NFT contract 14 | /// @author Tevaera Labs 15 | /// @notice Allows users to mint the guardian ONFT of InnovativeUnicorn 16 | /// @dev It extends ERC721 and ERC2981 standards 17 | contract InnovativeUnicornV1 is 18 | ERC721RoyaltyUpgradeable, 19 | ERC721EnumerableUpgradeable, 20 | PausableUpgradeable, 21 | ReentrancyGuardUpgradeable, 22 | ONFT721CoreUpgradeable 23 | { 24 | using CountersUpgradeable for CountersUpgradeable.Counter; 25 | 26 | /// @dev the safe address 27 | address payable private safeAddress; 28 | 29 | CountersUpgradeable.Counter private tokenIdCounter; 30 | 31 | /// @dev the token base uri 32 | string private tokenBaseUri; 33 | 34 | /// @dev Contract level metadata. 35 | string public contractURI; 36 | 37 | function initialize( 38 | address _lzEndpoint, 39 | address _safeAddress, 40 | uint256 _crosschainTransferFee, 41 | uint256 _minGasToTransferAndStore, 42 | string calldata _contractUri, 43 | string calldata _tokenBaseUri 44 | ) external initializer { 45 | __ERC721_init("Innovative Unicorn", "UNICORN"); 46 | __ERC721Enumerable_init(); 47 | __ERC721Royalty_init(); 48 | __Ownable_init_unchained(); 49 | __ONFT721CoreUpgradeable_init( 50 | _minGasToTransferAndStore, 51 | _lzEndpoint, 52 | _crosschainTransferFee, 53 | _safeAddress 54 | ); 55 | __Pausable_init(); 56 | __ReentrancyGuard_init(); 57 | 58 | // set contract uri which contains contract level metadata 59 | contractURI = _contractUri; 60 | // set safe address 61 | safeAddress = payable(_safeAddress); 62 | // set token base uri 63 | tokenBaseUri = _tokenBaseUri; 64 | 65 | // set default royalty to 2.5% 66 | _setDefaultRoyalty(_safeAddress, 250); 67 | } 68 | 69 | /// @dev Lets a contract admin set the URI for the contract-level metadata. 70 | function setContractURI(string calldata _uri) external onlyOwner { 71 | contractURI = _uri; 72 | } 73 | 74 | /// @dev Sets the token base uri 75 | /// @param _tokenBaseUri the token base uri 76 | function setTokenBaseUri( 77 | string calldata _tokenBaseUri 78 | ) external onlyOwner whenNotPaused { 79 | tokenBaseUri = _tokenBaseUri; 80 | } 81 | 82 | /// @dev Allows owner to update the safe wallet address 83 | /// @param _safeAddress the safe wallet address 84 | function updateSafeAddress( 85 | address payable _safeAddress 86 | ) external onlyOwner { 87 | require(_safeAddress != address(0), "Invalid address!"); 88 | safeAddress = _safeAddress; 89 | } 90 | 91 | /// @dev Withdraws the funds 92 | function withdraw(address token, uint256 amount) external onlyOwner { 93 | if (token == address(0)) { 94 | // Withdraw Ether 95 | require( 96 | address(this).balance >= amount, 97 | "Insufficient Ether balance" 98 | ); 99 | // Transfer Ether to the owner 100 | (bool success, ) = payable(msg.sender).call{value: amount}(""); 101 | require(success, "Ether transfer failed"); 102 | } else { 103 | // Withdraw ERC-20 tokens 104 | IERC20Upgradeable erc20Token = IERC20Upgradeable(token); 105 | uint256 contractBalance = erc20Token.balanceOf(address(this)); 106 | require(contractBalance >= amount, "Insufficient token balance"); 107 | // Transfer ERC-20 tokens to the owner 108 | require( 109 | erc20Token.transfer(msg.sender, amount), 110 | "Token transfer failed" 111 | ); 112 | } 113 | } 114 | 115 | /// @dev Debits a token from user's account to transfer it to another chain 116 | function _debitFrom( 117 | address _from, 118 | uint16, 119 | bytes memory, 120 | uint _tokenId 121 | ) internal virtual override { 122 | require( 123 | _from == _msgSender(), 124 | "ProxyONFT721: owner is not send caller" 125 | ); 126 | 127 | _burn(_tokenId); 128 | } 129 | 130 | /// @dev Credits a token to user's account received from another chain 131 | function _creditTo( 132 | uint16, 133 | address _toAddress, 134 | uint _tokenId 135 | ) internal virtual override { 136 | _safeMint(_toAddress, _tokenId); 137 | } 138 | 139 | // ----- system default functions ----- 140 | 141 | /// @dev Allows owner to pause sale if active 142 | function pause() public onlyOwner whenNotPaused { 143 | _pause(); 144 | } 145 | 146 | /// @dev Allows owner to activate sale 147 | function unpause() public onlyOwner whenPaused { 148 | _unpause(); 149 | } 150 | 151 | function _burn( 152 | uint256 tokenId 153 | ) internal override(ERC721Upgradeable, ERC721RoyaltyUpgradeable) { 154 | super._burn(tokenId); 155 | } 156 | 157 | function _beforeTokenTransfer( 158 | address from, 159 | address to, 160 | uint256 tokenId, 161 | uint256 batchSize 162 | ) 163 | internal 164 | override(ERC721Upgradeable, ERC721EnumerableUpgradeable) 165 | whenNotPaused 166 | { 167 | super._beforeTokenTransfer(from, to, tokenId, batchSize); 168 | } 169 | 170 | function supportsInterface( 171 | bytes4 interfaceId 172 | ) 173 | public 174 | view 175 | override( 176 | ERC721RoyaltyUpgradeable, 177 | ERC721EnumerableUpgradeable, 178 | ONFT721CoreUpgradeable 179 | ) 180 | returns (bool) 181 | { 182 | return super.supportsInterface(interfaceId); 183 | } 184 | 185 | function _baseURI() 186 | internal 187 | view 188 | override(ERC721Upgradeable) 189 | returns (string memory) 190 | { 191 | return tokenBaseUri; 192 | } 193 | 194 | function tokenURI( 195 | uint256 tokenId 196 | ) public view override(ERC721Upgradeable) returns (string memory) { 197 | return super.tokenURI(tokenId); 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /contracts/guardians/crosschain/InfluentialWerewolfV1.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.18; 3 | 4 | import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; 5 | import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; 6 | import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; 7 | import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; 8 | import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721RoyaltyUpgradeable.sol"; 9 | import "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol"; 10 | 11 | import "../../external/layer-zero/ONFT721CoreUpgradeable.sol"; 12 | 13 | /// @title InfluentialWerewolf NFT contract 14 | /// @author Tevaera Labs 15 | /// @notice Allows users to mint the guardian ONFT of InfluentialWerewolf 16 | /// @dev It extends ERC721 and ERC2981 standards 17 | contract InfluentialWerewolfV1 is 18 | ERC721RoyaltyUpgradeable, 19 | ERC721EnumerableUpgradeable, 20 | PausableUpgradeable, 21 | ReentrancyGuardUpgradeable, 22 | ONFT721CoreUpgradeable 23 | { 24 | using CountersUpgradeable for CountersUpgradeable.Counter; 25 | 26 | /// @dev the safe address 27 | address payable private safeAddress; 28 | 29 | CountersUpgradeable.Counter private tokenIdCounter; 30 | 31 | /// @dev the token base uri 32 | string private tokenBaseUri; 33 | 34 | /// @dev Contract level metadata. 35 | string public contractURI; 36 | 37 | function initialize( 38 | address _lzEndpoint, 39 | address _safeAddress, 40 | uint256 _crosschainTransferFee, 41 | uint256 _minGasToTransferAndStore, 42 | string calldata _contractUri, 43 | string calldata _tokenBaseUri 44 | ) external initializer { 45 | __ERC721_init("Influential Werewolf", "WEREWOL"); 46 | __ERC721Enumerable_init(); 47 | __ERC721Royalty_init(); 48 | __Ownable_init_unchained(); 49 | __ONFT721CoreUpgradeable_init( 50 | _minGasToTransferAndStore, 51 | _lzEndpoint, 52 | _crosschainTransferFee, 53 | _safeAddress 54 | ); 55 | __Pausable_init(); 56 | __ReentrancyGuard_init(); 57 | 58 | // set contract uri which contains contract level metadata 59 | contractURI = _contractUri; 60 | // set safe address 61 | safeAddress = payable(_safeAddress); 62 | // set token base uri 63 | tokenBaseUri = _tokenBaseUri; 64 | 65 | // set default royalty to 2.5% 66 | _setDefaultRoyalty(_safeAddress, 250); 67 | } 68 | 69 | /// @dev Lets a contract admin set the URI for the contract-level metadata. 70 | function setContractURI(string calldata _uri) external onlyOwner { 71 | contractURI = _uri; 72 | } 73 | 74 | /// @dev Sets the token base uri 75 | /// @param _tokenBaseUri the token base uri 76 | function setTokenBaseUri( 77 | string calldata _tokenBaseUri 78 | ) external onlyOwner whenNotPaused { 79 | tokenBaseUri = _tokenBaseUri; 80 | } 81 | 82 | /// @dev Allows owner to update the safe wallet address 83 | /// @param _safeAddress the safe wallet address 84 | function updateSafeAddress( 85 | address payable _safeAddress 86 | ) external onlyOwner { 87 | require(_safeAddress != address(0), "Invalid address!"); 88 | safeAddress = _safeAddress; 89 | } 90 | 91 | /// @dev Withdraws the funds 92 | function withdraw(address token, uint256 amount) external onlyOwner { 93 | if (token == address(0)) { 94 | // Withdraw Ether 95 | require( 96 | address(this).balance >= amount, 97 | "Insufficient Ether balance" 98 | ); 99 | // Transfer Ether to the owner 100 | (bool success, ) = payable(msg.sender).call{value: amount}(""); 101 | require(success, "Ether transfer failed"); 102 | } else { 103 | // Withdraw ERC-20 tokens 104 | IERC20Upgradeable erc20Token = IERC20Upgradeable(token); 105 | uint256 contractBalance = erc20Token.balanceOf(address(this)); 106 | require(contractBalance >= amount, "Insufficient token balance"); 107 | // Transfer ERC-20 tokens to the owner 108 | require( 109 | erc20Token.transfer(msg.sender, amount), 110 | "Token transfer failed" 111 | ); 112 | } 113 | } 114 | 115 | /// @dev Debits a token from user's account to transfer it to another chain 116 | function _debitFrom( 117 | address _from, 118 | uint16, 119 | bytes memory, 120 | uint _tokenId 121 | ) internal virtual override { 122 | require( 123 | _from == _msgSender(), 124 | "ProxyONFT721: owner is not send caller" 125 | ); 126 | 127 | _burn(_tokenId); 128 | } 129 | 130 | /// @dev Credits a token to user's account received from another chain 131 | function _creditTo( 132 | uint16, 133 | address _toAddress, 134 | uint _tokenId 135 | ) internal virtual override { 136 | _safeMint(_toAddress, _tokenId); 137 | } 138 | 139 | // ----- system default functions ----- 140 | 141 | /// @dev Allows owner to pause sale if active 142 | function pause() public onlyOwner whenNotPaused { 143 | _pause(); 144 | } 145 | 146 | /// @dev Allows owner to activate sale 147 | function unpause() public onlyOwner whenPaused { 148 | _unpause(); 149 | } 150 | 151 | function _burn( 152 | uint256 tokenId 153 | ) internal override(ERC721Upgradeable, ERC721RoyaltyUpgradeable) { 154 | super._burn(tokenId); 155 | } 156 | 157 | function _beforeTokenTransfer( 158 | address from, 159 | address to, 160 | uint256 tokenId, 161 | uint256 batchSize 162 | ) 163 | internal 164 | override(ERC721Upgradeable, ERC721EnumerableUpgradeable) 165 | whenNotPaused 166 | { 167 | super._beforeTokenTransfer(from, to, tokenId, batchSize); 168 | } 169 | 170 | function supportsInterface( 171 | bytes4 interfaceId 172 | ) 173 | public 174 | view 175 | override( 176 | ERC721RoyaltyUpgradeable, 177 | ERC721EnumerableUpgradeable, 178 | ONFT721CoreUpgradeable 179 | ) 180 | returns (bool) 181 | { 182 | return super.supportsInterface(interfaceId); 183 | } 184 | 185 | function _baseURI() 186 | internal 187 | view 188 | override(ERC721Upgradeable) 189 | returns (string memory) 190 | { 191 | return tokenBaseUri; 192 | } 193 | 194 | function tokenURI( 195 | uint256 tokenId 196 | ) public view override(ERC721Upgradeable) returns (string memory) { 197 | return super.tokenURI(tokenId); 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /contracts/guardians/GuardianBundlerV2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | pragma solidity 0.8.18; 3 | 4 | import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; 5 | import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; 6 | import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; 7 | import "./BalancerDragonV1.sol"; 8 | import "./InfluentialWerewolfV1.sol"; 9 | import "./InnovativeUnicornV1.sol"; 10 | import "./NomadicYetiV1.sol"; 11 | import "./SimplifierKrakenV1.sol"; 12 | 13 | /// @title Airdrop claim contract for Citizen ID & Karma Points 14 | /// @author Tevaera Labs 15 | /// @notice Claims airdropped Citizen ID & Karma Points 16 | /// @dev Uses CitizenID and KarmaPoint contracts for minting 17 | contract GuardianBundlerV2 is OwnableUpgradeable, PausableUpgradeable { 18 | /// @dev the safe address 19 | address payable private safeAddress; 20 | 21 | /// @dev the instances of guardian contracts 22 | BalancerDragonV1 internal balancerDragon; 23 | InfluentialWerewolfV1 internal influentialWerewolf; 24 | InnovativeUnicornV1 internal innovativeUnicorn; 25 | NomadicYetiV1 internal nomadicYeti; 26 | SimplifierKrakenV1 internal simplifierKraken; 27 | 28 | /// @dev the bundle price in ETH 29 | uint256 public bundlePrice; 30 | 31 | function initialize( 32 | BalancerDragonV1 _balancerDragon, 33 | InfluentialWerewolfV1 _influentialWerewolf, 34 | InnovativeUnicornV1 _innovativeUnicorn, 35 | NomadicYetiV1 _nomadicYeti, 36 | SimplifierKrakenV1 _simplifierKraken, 37 | address _safeAddress, 38 | uint256 _bundlePrice 39 | ) external initializer { 40 | balancerDragon = _balancerDragon; 41 | influentialWerewolf = _influentialWerewolf; 42 | innovativeUnicorn = _innovativeUnicorn; 43 | nomadicYeti = _nomadicYeti; 44 | simplifierKraken = _simplifierKraken; 45 | safeAddress = payable(_safeAddress); 46 | bundlePrice = _bundlePrice; 47 | } 48 | 49 | function initializeV2() public reinitializer(2) { 50 | __Ownable_init(); 51 | __Pausable_init(); 52 | } 53 | 54 | /// @notice Users gets citizen id and karma points if eligible 55 | /// @dev Mints citizen id and karma points 56 | function mintBundle() external payable whenNotPaused { 57 | // price validation 58 | require(msg.value == bundlePrice, "Invalid amount"); 59 | 60 | // mint all guardians 61 | if (balancerDragon.balanceOf(msg.sender) == 0) { 62 | balancerDragon.mintForBundler(msg.sender); 63 | } 64 | if (influentialWerewolf.balanceOf(msg.sender) == 0) { 65 | influentialWerewolf.mintForBundler(msg.sender); 66 | } 67 | if (innovativeUnicorn.balanceOf(msg.sender) == 0) { 68 | innovativeUnicorn.mintForBundler(msg.sender); 69 | } 70 | if (nomadicYeti.balanceOf(msg.sender) == 0) { 71 | nomadicYeti.mintForBundler(msg.sender); 72 | } 73 | if (simplifierKraken.balanceOf(msg.sender) == 0) { 74 | simplifierKraken.mintForBundler(msg.sender); 75 | } 76 | } 77 | 78 | /// @dev Owner can update the citizen id contract address 79 | function setBalancerDragon( 80 | BalancerDragonV1 _balancerDragon 81 | ) external onlyOwner { 82 | balancerDragon = _balancerDragon; 83 | } 84 | 85 | /// @dev Owner can update the citizen id contract address 86 | function setInfluentialWerewolf( 87 | InfluentialWerewolfV1 _influentialWerewolf 88 | ) external onlyOwner { 89 | influentialWerewolf = _influentialWerewolf; 90 | } 91 | 92 | /// @dev Owner can update the citizen id contract address 93 | function setInnovativeUnicorn( 94 | InnovativeUnicornV1 _innovativeUnicorn 95 | ) external onlyOwner { 96 | innovativeUnicorn = _innovativeUnicorn; 97 | } 98 | 99 | /// @dev Owner can update the citizen id contract address 100 | function setNomadicYeti(NomadicYetiV1 _nomadicYeti) external onlyOwner { 101 | nomadicYeti = _nomadicYeti; 102 | } 103 | 104 | /// @dev Owner can update the citizen id contract address 105 | function setSimplifierKraken( 106 | SimplifierKrakenV1 _simplifierKraken 107 | ) external onlyOwner { 108 | simplifierKraken = _simplifierKraken; 109 | } 110 | 111 | /// @dev Allows owner to update the safe wallet address 112 | /// @param _safeAddress the safe wallet address 113 | function updateSafeAddress( 114 | address payable _safeAddress 115 | ) external onlyOwner { 116 | require(_safeAddress != address(0), "Invalid address!"); 117 | safeAddress = _safeAddress; 118 | } 119 | 120 | /// @dev Withdraws the funds 121 | function withdraw(address token, uint256 amount) external onlyOwner { 122 | if (token == address(0)) { 123 | // Withdraw Ether 124 | require( 125 | address(this).balance >= amount, 126 | "Insufficient Ether balance" 127 | ); 128 | 129 | // Transfer Ether to the owner 130 | (bool success, ) = payable(msg.sender).call{value: amount}(""); 131 | require(success, "Ether transfer failed"); 132 | } else { 133 | // Withdraw ERC-20 tokens 134 | IERC20Upgradeable erc20Token = IERC20Upgradeable(token); 135 | uint256 contractBalance = erc20Token.balanceOf(address(this)); 136 | require(contractBalance >= amount, "Insufficient token balance"); 137 | 138 | // Transfer ERC-20 tokens to the owner 139 | require( 140 | erc20Token.transfer(msg.sender, amount), 141 | "Token transfer failed" 142 | ); 143 | } 144 | } 145 | 146 | /// @dev Owner can pause the claim 147 | function pause() external onlyOwner whenNotPaused { 148 | _pause(); 149 | } 150 | 151 | /// @dev Owner can activate the claim 152 | function unpause() external onlyOwner whenPaused { 153 | _unpause(); 154 | } 155 | 156 | //////////////////////// V3 Changes //////////////////////// 157 | // Add a function that enables addresses listed on the whitelist to mint tokens on behalf of other addresses. 158 | 159 | /// @dev the list of whitelisted callers 160 | mapping(address => bool) public whitelistedCallers; 161 | 162 | /// @dev Allows owner to blacklist any wallet address across Tevaera platform 163 | /// @param addresses the list of wallet addresses that need to be blocked 164 | function whitelistCallers(address[] calldata addresses) external onlyOwner { 165 | uint256 len = addresses.length; 166 | for (uint256 i = 0; i < len; ) { 167 | require(addresses[i] != address(0), "Invalid address"); 168 | 169 | if (!whitelistedCallers[addresses[i]]) { 170 | whitelistedCallers[addresses[i]] = true; 171 | } 172 | 173 | unchecked { 174 | ++i; 175 | } 176 | } 177 | } 178 | 179 | /// @dev Mint token for a specified address when called by whitelisted callers 180 | function mintForAddress(address recipient) external payable whenNotPaused { 181 | require(whitelistedCallers[msg.sender], "Caller is not whitelisted"); 182 | 183 | // price validation 184 | require(msg.value == bundlePrice, "Invalid amount"); 185 | 186 | // mint all guardians 187 | if (balancerDragon.balanceOf(recipient) == 0) { 188 | balancerDragon.mintForBundler(recipient); 189 | } 190 | if (influentialWerewolf.balanceOf(recipient) == 0) { 191 | influentialWerewolf.mintForBundler(recipient); 192 | } 193 | if (innovativeUnicorn.balanceOf(recipient) == 0) { 194 | innovativeUnicorn.mintForBundler(recipient); 195 | } 196 | if (nomadicYeti.balanceOf(recipient) == 0) { 197 | nomadicYeti.mintForBundler(recipient); 198 | } 199 | if (simplifierKraken.balanceOf(recipient) == 0) { 200 | simplifierKraken.mintForBundler(recipient); 201 | } 202 | } 203 | } 204 | --------------------------------------------------------------------------------