{"id":19147799,"url":"https://github.com/refcell/spades","last_synced_at":"2025-09-05T00:34:37.038Z","repository":{"id":44606301,"uuid":"454237278","full_name":"refcell/spades","owner":"refcell","description":"Sealed Price Appraisals for Deterministic Emissions","archived":false,"fork":false,"pushed_at":"2022-02-05T03:11:21.000Z","size":1460,"stargazers_count":30,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-05T15:54:43.217Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/refcell.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-02-01T02:23:49.000Z","updated_at":"2025-03-23T13:38:50.000Z","dependencies_parsed_at":"2022-09-13T14:20:56.384Z","dependency_job_id":null,"html_url":"https://github.com/refcell/spades","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/refcell%2Fspades","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/refcell%2Fspades/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/refcell%2Fspades/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/refcell%2Fspades/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/refcell","download_url":"https://codeload.github.com/refcell/spades/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252804206,"owners_count":21806769,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T07:52:24.569Z","updated_at":"2025-05-07T03:04:09.384Z","avatar_url":"https://github.com/refcell.png","language":"Solidity","funding_links":[],"categories":[],"sub_categories":[],"readme":"# spades • [![tests](https://github.com/abigger87/spades/actions/workflows/tests.yml/badge.svg)](https://github.com/abigger87/spades/actions/workflows/tests.yml) [![lints](https://github.com/abigger87/spades/actions/workflows/lints.yml/badge.svg)](https://github.com/abigger87/spades/actions/workflows/lints.yml) ![GitHub](https://img.shields.io/github/license/abigger87/spades)  ![GitHub package.json version](https://img.shields.io/github/package-json/v/abigger87/spades)\n\n**S**ealed **P**rice **A**ppraisals for **D**eterministic **E**missions.\n\n\u003c!-- \u003ch4 align=\"center\"\u003e\n\n✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨\n\n\u003c/h4\u003e --\u003e\n\n```m\n??????????????????????????????????????????????? . ################################################\n??????????????????????????????????????????????  %  ###############################################\n?????????????????????????????????????????????  %*:  ##############################################\n????????????????????????????????????????????  %#*?:  #############################################\n??????????????????????????????????????????  ,%##*??:.  ###########################################\n????????????????????????????????????????  ,%##*?*#*??:.  #########################################\n??????????????????????????????????????  ,%###*??*##*???:.  #######################################\n????????????????????????????????????  ,%####*???*###*????:.  #####################################\n??????????????????????????????????  ,%####**????*####**????:.  ###################################\n????????????????????????????????  ,%#####**?????*#####**?????:.  #################################\n???????????????????????????????  %######**??????*######**??????:  ################################\n??????????????????????????????  %######**???????*#######**??????:  ###############################\n?????????????????????????????  %######***???????*#######***??????:  ##############################\n?????????????????????????????  %######***???????*#######***??????:  ##############################\n?????????????????????????????  %######***???????*#######***??????:  ##############################\n??????????????????????????????  %######**??????***######**??????:  ###############################\n???????????????????????????????  '%######****:^%*:^%****??????:'  ################################\n?????????????????????????????????   '%####*:'  %*:  '%*????:'   ##################################\n???????????????????????????????????           %#*?:           ####################################\n??????????????????????????????????????????  ,%##*??:.  ###########################################\n????????????????????????????????????????  .%###***???:.  #########################################\n???????????????????????????????????????                   ########################################\n????????????????????????????????????????????????*#################################################\n```\n\n\n## Overview ♠️\n\nCurrent mints sacrifice both price-discovery and gas efficiency for ordering.\n\nThis leads to gas wars and bag shilling, often enabled by gated whitelists.\n\n[Spades](https://github.com/abigger87/spades) is an attempt to maximize the ERC721 drop tradeoff by building off of [Cloaks](https://github.com/abigger87/cloaks).\n\nTL;DR - [Spades](https://github.com/abigger87/spades) is an ERC721 with a builtin commit-reveal scheme to determine the initial clearing price of an LBP.\n\n## How it works ♠️\n\nSpades is an ERC721 Token with built-in minting broken down into four phases.\n\n#### Phase 1 - Commitments\n\nSpades begins with a commit phase that lasts from `commitStart` to `revealStart`.\n\nDuring the commit phase, anyone can permissionlessly call the `commit(bytes32)` function, passing in a hashed commitment (32 bytes).\n\nThe hashed commitment includes an appraisal price (at which each ERC721 token should be valued) along with a `blindingFactor` that prevents hash table attacks.\n\nCalling the commitment also requires a `depositAmount` of ether or the `depositToken` to prevent commitment spam.\n\n#### Phase 2 - Reveals\n\nAt this point, there are a bunch of commitments stored in the Spades Contract.\n\nOnce the Reveal Phase begins when the `block.timestamp` reaches `revealStart`, participants from phase 1 can reveal their appraisal by calling the `reveal(uint256,bytes32)` function.\n\nWhere the first argument is the appraisal value and the second is the `blindingFactor`.\n\nOnce this function is called, the sender's sealed appraisal becomes public.\n\n⚠️ NOTE ⚠️ If a commit phase participant fails to reveal their commitment, they will incur the Spade's `MAX_LOSS_PENALTY` (in bips) on their deposit. After the reveal phase, the user may call `lostReveal()` to extract the remainder of their deposit.\n\n#### Phase 3 - Restricted Mint\n\nWhen the timestamp reaches `restrictedMintStart`, the reveal phase ends and the Restricted mint period begins.\n\nSince all appraisals have been revealed, a `clearingPrice` can be calculated as the mean of all committed appraisals.\n\nThis is the starting mint price.\n\nParticipants who revealed their appraisals can now call `restrictedMint()` to mint one ERC721 token at a **discounted** price.\n\nCalling `restrictedMint()` requires the discounted price to be sent in ether or will be transferred from the user for the specified `depositToken`.\n\nWhere the discount is proportional to how close their appraisal value was to the calculated `clearingPrice`.\n\n⚠️ NOTE ⚠️ Outliers (normally a zscore of 3, but for tighter bounds Spades uses a zscore of 2) cannot mint.\n\nAlso note, the max discount factor is 2,000 bips or 20% off the `clearingPrice`.\n\nTo view their discount price, a particpant can call the `restrictedMintPrice()` function.\n\nTo check restricted minting eligibility, a participany can call the `canRestrictedMint()` function.\n\nAdditionally, a user can choose to `forgo()` their mint allocation (outliers must do this to recover part of their deposit).\n\nThe `forgo()` function will return the `depositAmount` less a loss penalty inversely related to how close their appraisal was to the `clearingPrice`.\n\n⚠️ NOTE ⚠️ Outliers will lose the `MAX_LOSS_PENALTY`.\n\n#### Phase 4 - Public LBP\n\nAt this point, if not all ERC721 tokens are minted (`tokenSupply \u003c MAX_TOKEN_SUPPLY`), minting is enabled for everyone, including non-commitment participants.\n\nWhen `block.timestamp` is greater than or equal to `publicMintStart`, the `mint(uint256)` function can be called, supplying the number of tokens to be minted.\n\nThe public `mint` function requires ether to be sent or the `depositToken` will be transferred at an initial amount equal to the `clearingPrice` (or the `minPrice` if `clearingPrice \u003c minPrice`).\n\n**With one important caveat** - the price to mint is modeled after an LBP.\n\nThat is, on each new token minted, the price to mint another token increase by `priceIncreasePerMint` and on each new block, the price decreases by `priceDecayPerBlock`.\n\n⚠️ NOTE ⚠️ no more than `MAX_MINT_PER_ACCOUNT` can be minted per account (except for the commitment participants who can mint `MAX_MINT_PER_ACCOUNT + 1`).\n\n\n## Motivation ♠️\n\nEssentially the same as [cloaks](https://github.com/abigger87/cloaks).\n\nMints suck...\n\nThey're difficult to mint, oft impossible.\n\nThe mint price is fixed - artists and creators don't realize upside.\n\nWhitelists, gating methods, and gas wars prevent any semblance of a fair mint.\n\n## Extremely Technical Documentation ♠️\n\n#### Phases\n\n\u003cimg src='./assets/phases.jpg' width='500'\u003e\n\n#### Rolling Variance Calculation\n\n\u003cimg src='./assets/rolling_variance.png' width='500'\u003e\n\n#### Rolling Mean Calculation\n\n\u003cimg src='./assets/rolling_mean.png' width='500'\u003e\n\n## Blueprint ♠️\n\n```ml\nlib\n├─ ds-test — https://github.com/dapphub/ds-test\n├─ forge-std — https://github.com/brockelmore/forge-std\n├─ solmate — https://github.com/Rari-Capital/solmate\n├─ clones-with-immutable-args — https://github.com/wighawag/clones-with-immutable-args\nsrc\n├─ tests\n│  └─ Spade.t — \"Spade Tests\"\n└─ Spade — \"Spade ERC721 Contract\"\n```\n\n## Development ♠️\n\nA [Spade](https://github.com/abigger87/spades) is an extensible ERC721 implementation with a commit-reveal scheme and lbp built _into_ the ERC721 contract itself.\nThe only contract is located in [src/](./src/) called [Spade](./src/Spade.sol).\n\nIt is an abstract contract and requires an implementation for `tokenURI` as in [MockSpade](./src/test/mocks/MockSpade.sol);\n\nBoth [DappTools](https://dapp.tools/) and [Foundry](https://github.com/gaskonst/foundry) are supported. Installation instructions for both are included below.\n\n#### Install DappTools\n\nInstall DappTools using their [installation guide](https://github.com/dapphub/dapptools#installation).\n\n#### First time with Forge/Foundry?\n\nSee the official Foundry installation [instructions](https://github.com/gakonst/foundry/blob/master/README.md#installation).\n\nDon't have [rust](https://www.rust-lang.org/tools/install) installed?\nRun\n```bash\ncurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n```\n\nThen, install the [foundry](https://github.com/gakonst/foundry) toolchain installer (`foundryup`) with:\n```bash\ncurl -L https://foundry.paradigm.xyz | bash\n```\n\nNow that you've installed the `foundryup` binary,\nanytime you need to get the latest `forge` or `cast` binaries,\nyou can run `foundryup`.\n\nSo, simply execute:\n```bash\nfoundryup\n```\n\n🎉 Foundry is installed! 🎉\n\n#### Setup\n\n```bash\nmake\n# OR #\nmake setup\n```\n\n#### Build\n\n```bash\nmake build\n```\n\n#### Run Tests\n\n```bash\nmake test\n```\n\n#### Configure Foundry\n\nUsing [foundry.toml](./foundry.toml), Foundry is easily configurable.\n\n## License ♠️\n\n[AGPL-3.0-only](https://github.com/abigger87/spades/blob/master/LICENSE)\n\n## Acknowledgements ♠️\n\n- [Glass.xyz's LBP ERC721](https://github.com/GlassProtocol/LBPERC721/blob/main/src/LBPERC721.sol)\n- [commit-reveal schemes](https://medium.com/swlh/exploring-commit-reveal-schemes-on-ethereum-c4ff5a777db8)\n- [foundry](https://github.com/gakonst/foundry)\n- [solmate](https://github.com/Rari-Capital/solmate)\n- [forge-std](https://github.com/brockelmore/forge-std)\n- [clones-with-immutable-args](https://github.com/wighawag/clones-with-immutable-args).\n- [Brock Elmore](https://github.com/brockelmore) for [forge-std](https://github.com/brockelmore/forge-std)\n- [foundry-toolchain](https://github.com/onbjerg/foundry-toolchain) by [onbjerg](https://github.com/onbjerg).\n- [forge-template](https://github.com/FrankieIsLost/forge-template) by [FrankieIsLost](https://github.com/FrankieIsLost).\n- [Georgios Konstantopoulos](https://github.com/gakonst) for [forge-template](https://github.com/gakonst/forge-template) resource.\n\n## Disclaimer ♠️\n\n_These smart contracts are being provided as is. No guarantee, representation or warranty is being made, express or implied, as to the safety or correctness of the user interface or the smart contracts. They have not been audited and as such there can be no assurance they will work as intended, and users may experience delays, failures, errors, omissions, loss of transmitted information or loss of funds. The creators are not liable for any of the foregoing. Users should proceed with caution and use at their own risk._\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frefcell%2Fspades","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frefcell%2Fspades","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frefcell%2Fspades/lists"}