diff --git a/.gitignore b/.gitignore index b50bf07e..48956ed2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -artifacts cache types lcov.info @@ -6,6 +5,8 @@ lcov.info dist out node_modules/ +**/*.dbg.json +artifacts/* .DS_Store .idea/ .yarn/* @@ -21,3 +22,4 @@ temp/ broadcast/ .env* !.env.example +.npmignore diff --git a/README.md b/README.md index e8e070b1..3591cf86 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,23 @@ # tokenize.it -These smart contracts implement [tokenize.it](https://tokenize.it/)'s tokenized cap table management. They are released under the GNU General Public License version 3 (GPL-3.0). +These smart contracts implement [tokenize.it](https://tokenize.it/)'s tokenized cap table management. # Getting Started +## ... for usage + +``` +yarn add @tokenizeit/contracts +``` + +or + +``` +npm install @tokenizeit/contracts +``` + +## ... for development + 1. clone repository: `git clone --recurse-submodules git@github.com:corpus-ventures/tokenize.it-smart-contracts.git` 2. enter project root folder: `cd tokenize.it-smart-contracts` 3. if repository was cloned without submodules, init submodules now (not necessary if cloning command above was used): `git submodule update --init --recursive` @@ -19,9 +33,13 @@ If you are missing dependencies: - yarn: `npm install yarn` - foundry: [install guide](https://book.getfoundry.sh/getting-started/installation) -For information regarding testing, please go to [testing](docs/testing.md). +For information regarding: + +- testing, please go to [testing](docs/testing.md). +- deployment, please go to [deployment](docs/deployment.md). +- npm publishing, please go to [npm publishing](docs/npm_publishing.md). -For information regarding deployment, please go to [deployment](docs/deployment.md). +For # Main Concept @@ -53,12 +71,13 @@ In order to improve UX, though, a frontend will be offered. In order to improve Two contracts implement [EIP-2771](https://eips.ethereum.org/EIPS/eip-2771), and therefore use a trusted forwarder. The forwarder will be set in the constructor and there is no way to change it after deployment. The forwarder used will be the openGSN v2 forwarder deployed on mainnet. Some information about this contract: - [Documentation and addresses](https://docs-v2.opengsn.org/networks/ethereum/mainnet.html) +- [Code](https://github.com/opengsn/gsn/blob/v2.2.5/packages/contracts/src/forwarder/Forwarder.sol) - [Audit reports](https://docs-v2.opengsn.org/audits.html) -- Was deployed 2022-04-21 -- It's address is **0xAa3E82b4c4093b4bA13Cb5714382C99ADBf750cA** -- Visit on [etherscan](https://etherscan.io/address/0xaa3e82b4c4093b4ba13cb5714382c99adbf750ca) ([see transactions here](https://etherscan.io/txsInternal?a=0xAa3E82b4c4093b4bA13Cb5714382C99ADBf750cA&&m=advanced&p=1)) -- This [dashboard](https://dune.com/oren/meta-transactions-on-ethereum-over-time) lists the forwarder as second most active forwarder contract with over 2000 transactions executed -- it is also used in our [tests](./test/ContinuousFundraisingERC2771.t.sol). +- Deployment: **0xAa3E82b4c4093b4bA13Cb5714382C99ADBf750cA** + - deployed 2022-04-21 + - Visit on [etherscan](https://etherscan.io/address/0xaa3e82b4c4093b4ba13cb5714382c99adbf750ca) ([see transactions here](https://etherscan.io/txsInternal?a=0xAa3E82b4c4093b4bA13Cb5714382C99ADBf750cA&&m=advanced&p=1)) + - This [dashboard](https://dune.com/oren/meta-transactions-on-ethereum-over-time) lists the forwarder as second most active forwarder contract with over 2000 transactions executed + - used in our [tests](./test/ContinuousFundraisingERC2771.t.sol). The platform will maintain a hot wallet (EOA) in order to send transactions to the forwarder contract. This results in the following flow: diff --git a/docs/npm_publishing.md b/docs/npm_publishing.md new file mode 100644 index 00000000..aeb31dd9 --- /dev/null +++ b/docs/npm_publishing.md @@ -0,0 +1,19 @@ +# Publishing to npm + +The smart contracts are published to npm as a package. The package name is `@tokenizeit/contracts`. This makes it easy to use the contracts in other projects. + +Currently, no automated publishing is set up. Publishing is done manually. To publish a new version, follow these steps: + +1. First test without publishing: + + ```bash + npm publish --access public --dry-run + ``` + +2. Check if all necessary files are contained and no secrets are leaked. +3. If everything is fine, publish: + ```bash + npm publish --access public + ``` + +Sadly, `yarn publish` did not work at the time of writing. It appeared to have trouble with the 2FA. diff --git a/example.ts b/example.ts deleted file mode 100644 index 38bdccd9..00000000 --- a/example.ts +++ /dev/null @@ -1,42 +0,0 @@ -// To run the example: -// yarn build -// yarn hardhat node -// yarn hardhat run --network localhost scripts/deploy.ts -// copy and paste contract address -// yarn ts-node example.ts - -import {Token__factory} from './dist/types' -import {ethers} from 'ethers' - -const TOKEN_CONTRACT_ADDRESS = '0x5FbDB2315678afecb367f032d93F642f64180aa3' - -async function main() { - - // can be an RPC URL or injected e.g. by MetaMask - const provider = new ethers.providers.JsonRpcProvider('http://127.0.0.1:8545') - - const signer = new ethers.Wallet( - '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', // private key - provider - ) - - const tokenContracInstance = Token__factory.connect(TOKEN_CONTRACT_ADDRESS, signer); - - // call contract (read) - const symbol = await tokenContracInstance.symbol() - console.log('Token Symbol: ' + symbol) - - // send transaction (write, change contract state) - await tokenContracInstance.pause() - // call contract (read) - console.log('Paused: ' + await tokenContracInstance.paused()) - - // send transaction (write, change contract state) - await tokenContracInstance.unpause() - // call contract (read) - console.log('Paused: ' + await tokenContracInstance.paused()) - - -} - -main() \ No newline at end of file diff --git a/foundry.toml b/foundry.toml index 7df87223..2bc811e7 100644 --- a/foundry.toml +++ b/foundry.toml @@ -2,8 +2,9 @@ fuzz-runs = 10_000 [profile.default] +# via-ir = true # Enable the IR-based optimizer (yul) optimizer = true -optimizer_runs = 2000 +optimizer_runs = 10_000 gas_reports = ["AllowList", "ContinuousFundraising", "FeeSettings", "PersonalInvite", "PersonalInviteFactory", "Token"] [rpc_endpoints] diff --git a/hardhat.config.ts b/hardhat.config.ts index 38736ed7..ae6be276 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -33,9 +33,11 @@ const config: HardhatUserConfig = { version: "0.8.17", settings: { optimizer: { - enabled: false, - runs: 200, + enabled: true, + runs: 10000, }, + // viaIR: true, + // outputSelection: { "*": { "*": ["storageLayout"] } }, }, }, networks: { @@ -49,7 +51,8 @@ const config: HardhatUserConfig = { }, goerli: { url: process.env.GOERLI_RPC_URL || "", - accounts: process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], + accounts: + process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], }, }, gasReporter: { diff --git a/package.json b/package.json index 6de80262..0f6cff5f 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,53 @@ { - "name": "hardhat-project", + "name": "@tokenize.it/contracts", + "version": "4.0.0", + "description": "Tokenize.it smart contracts for company tokenization, public fundraising, private offers and employee participation", + "keywords": [ + "evm", + "ethereum", + "smart contract", + "tokenize.it" + ], + "homepage": "https://github.com/corpus-io/tokenize.it-smart-contracts", + "license": "AGPL-3.0", + "bugs": { + "url": "https://github.com/corpus-io/tokenize.it-smart-contracts/issues", + "email": "info@corpus.io" + }, + "contributors": [ + { + "name": "malteish", + "email": "malteish@corpus.io" + }, + { + "name": "Christoph Jentzsch", + "email": "christoph@corpus.io" + } + ], + "files": [ + "/contracts/**/*.sol", + "/artifacts/contracts/**/*[!.dbg].json", + "/types/**/*", + "/docs/**/*", + "hardhat.config.ts", + "tsconfig.json" + ], + "repository": { + "type": "git", + "url": "https://github.com/corpus-io/tokenize.it-smart-contracts.git" + }, "types": "./dist/types/index.d.ts", "main": "./dist/types/index.js", "installConfig": { "hoistingLimits": "workspaces" }, + "publishConfig": { + "ignore": [ + "!build/", + "src/", + "test/" + ] + }, "devDependencies": { "@foundry-rs/hardhat-forge": "^0.1.17", "@nomiclabs/hardhat-ethers": "^2.1.1", @@ -28,6 +71,7 @@ "ethers": "^5.6.6", "hardhat": "^2.10.2", "hardhat-gas-reporter": "^1.0.8", + "npmignore": "^0.3.0", "prettier": "^2.8.0", "prettier-plugin-solidity": "^1.0.0", "solhint": "^3.3.7", @@ -41,6 +85,7 @@ "@openzeppelin/contracts": "4.8.0" }, "scripts": { + "prepack": "yarn npmignore --auto && yarn test && yarn build ", "build": "yarn hardhat compile && yarn tsc --declaration", "test": "forge test --no-match-test Mainnet", "coverage": "forge coverage --report lcov && genhtml lcov.info --branch-coverage --output-directory=./coverage" diff --git a/yarn.lock b/yarn.lock index 5f503cbe..a46087c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7189,6 +7189,13 @@ normalize-url@^6.0.1: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== +npmignore@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/npmignore/-/npmignore-0.3.0.tgz#1431207b2fb9912e5f98706717267543c04169d1" + integrity sha512-lJw7pfo+dqj/scV5s+3SWpEuLAgJHVPs3vJ/B8FzA8zYQLiTs+TnPiQTYNCu1KPMuDaGm/U5DRItJ7xYb2qVGQ== + dependencies: + minimist "^1.2.6" + number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"