Skip to content

Commit 37dfd33

Browse files
committed
Add documentation for custom validation hook and supply schedule
1 parent a2f0c2b commit 37dfd33

3 files changed

Lines changed: 128 additions & 0 deletions

File tree

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---
2+
id: custom-validation-hook
3+
title: Custom Validation Hook
4+
sidebar_position: 1
5+
---
6+
7+
# Custom Validation Hook
8+
This guide will outline how to create a custom validation hook for a CCA auction. Hooks are powerful extensions to CCA which unlock a wide range of features like bidding limits, allowlisting, and more.
9+
10+
## Prerequisites
11+
- [Foundry](https://getfoundry.sh/introduction/installation)
12+
- Basic understanding of the CCA contracts and Solidity
13+
14+
If you haven't already, please check out the [quickstart guide](../quickstart/local-deployment.md).
15+
16+
## Interface
17+
All validation hooks must implement the [IValidationHook](https://github.com/Uniswap/continuous-clearing-auction/blob/main/src/interfaces/IValidationHook.sol) interface.
18+
19+
```solidity
20+
interface IValidationHook {
21+
function validate(uint256 maxPrice, uint128 amount, address owner, address sender, bytes calldata hookData) external;
22+
}
23+
```
24+
25+
This function is called by the auction contract during bid submission. To reject a bid, your hook MUST revert.
26+
27+
### Parameters
28+
- `maxPrice`: The maximum price the bidder is willing to pay
29+
- `amount`: The amount of currency the user is bidding
30+
- `owner`: The address of the user who will receive any purchased tokens or refunded currency
31+
- `sender`: The address of the user who is submitting the bid
32+
- `hookData`: Any extra data
33+
34+
Note that `hookData` is arbitrarily specified by the bidder and should NOT be trusted.
35+
36+
## Introspection
37+
It is highly recommended to implement basic [ERC165](https://eips.ethereum.org/EIPS/eip-165) introspection support for your hook. This will allow users to query for which capabilities the hook supports.
38+
39+
```solidity
40+
interface IERC165 {
41+
function supportsInterface(bytes4 interfaceId) external view returns (bool);
42+
}
43+
```
44+
45+
You can also inherit from the base contract [ValidationHookIntrospection](https://github.com/Uniswap/continuous-clearing-auction/blob/main/src/periphery/validationHooks/ValidationHookIntrospection.sol) which automatically implements support for `IERC165` and `IValidationHook`. Make sure to override the `supportsInterface` function to return `true` for your specific hook interface.
46+
47+
```solidity
48+
interface ICustomValidationHook is IValidationHook, IERC165 {
49+
// Your custom hook interface here
50+
}
51+
52+
contract CustomValidationHook is ValidationHookIntrospection {
53+
function supportsInterface(bytes4 interfaceId) public view override(ValidationHookIntrospection, IERC165) returns (bool) {
54+
return super.supportsInterface(interfaceId) || interfaceId == type(ICustomValidationHook).interfaceId;
55+
}
56+
}
57+
```
58+
59+
## Deployment
60+
Hooks must be deployed before the auction is created as they must be set in the `validationHook` parameter of the auction. If your hook requires that only the auction is able to call `validate`, you can initialize the hook after deployment.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
id: supply-schedule
3+
title: Supply schedule
4+
sidebar_position: 2
5+
---
6+
7+
# Supply schedule
8+
This guide will cover what a supply schedule is in the context of CCA and how it can be configured.
9+
10+
## Prerequisites
11+
- [Foundry](https://getfoundry.sh/introduction/installation)
12+
- Basic understanding of the CCA contracts and Solidity
13+
14+
If you haven't already, please check out the [quickstart guide](../quickstart/local-deployment.md).
15+
16+
## High-level overview
17+
The supply schedule defines the _rate_ of token issuance over the course of the auction. The auction creator can configure exactly how many tokens are sold at each block of the auction.
18+
19+
A well-designed supply schedule does three things at once: it **creates meaningful incentives to participate early**, **keeps the auction attractive for late arrivals**, and **anchors a robust final clearing price**.
20+
21+
In practice, this is best achieved with a **moderately convex supply curve** that releases supply gradually, combined with a **large final block** of tokens. Early supply is sufficient to reward early bidders, later supply preserves participation throughout the auction, and the large end block ensures that the final clearing price reflects broad demand and is difficult to manipulate.
22+
23+
## Implementation
24+
The supply schedule is implemented as a series of `uint64` values that represent the per-block issuance rate in MPS (milli-bips), and the number of blocks the rate is valid for. For example, the following supply schedule: `(100e3, 50), (200e3, 25)` represents a supply schedule where `100,000 mps` is sold each block for `50` consecutive blocks, and `200,000 mps` is sold each block for the next `25` blocks.
25+
26+
> Note that 1 mps represents one thousandth of a basis point, with one million mps representing 100% of the supply.
27+
28+
Thus, the above schedule sells 1% per block for the first 50 blocks, and 2% per block for the next 25 blocks, resulting in selling 1 * 50 + 2 * 25 = 100% of the supply. This schedule is _valid_ since the cumulative issuance rate is 100%.
29+
30+
### Encoding
31+
The supply schedule is encoded as a packed bytes array of `uint64` values. Each `uint64` value represents an encoded pair of `(uint24 mps, uint40 blocks)`. The `mps` value is the per-block issuance rate in MPS, and the `blocks` value is the number of blocks the rate is valid for.
32+
33+
Use `abi.encodePacked` to pack the `uint64` values into a bytes array.
34+
35+
You can leverage the [AuctionStepsBuilder](https://github.com/Uniswap/continuous-clearing-auction/blob/main/test/utils/AuctionStepsBuilder.sol) helper library to build the auction steps data locally.
36+
37+
### Usage
38+
The supply schedule is passed to the auction as a parameter within the `AuctionParameters` struct when deploying a new auction as the `auctionStepsData` parameter.
39+
40+
## Guidelines
41+
Integrators and teams should be aware of the following best practices when designing a supply schedule:
42+
- Schedules should be monotonically increasing (each step having a higher % rate than the previous step)
43+
- Early steps should not sell a significant percentage of the supply
44+
- The last step should be **one block** in length and should sell a **significant** percentage of the supply
45+
46+
### Price durability
47+
Since the final clearing price becomes the starting price of the token on the AMM, it is crucial that the final block sells a significant percentage of the supply. This makes manipulation of the final clearing price difficult.
48+
49+
Additionally, it still allows for late bidders to receive a meaningful amount of tokens.
50+
51+
There is no single correct choice, but in practice the end block should be **large enough that the final clearing price cannot be meaningfully moved by new bids**, while not so large that it dominates the entire auction.
52+
53+
As a rough guideline:
54+
- End blocks on the order of **20–40% of total supply** tend to work well across a wide range of market conditions.
55+
- Below this range, the final price becomes increasingly sensitive to small amounts of late demand.
56+
- Above this range, the auction begins to resemble a single-period sale, weakening early-participation incentives.
57+
58+
The appropriate size ultimately depends on the expected scale of participation, the importance of the final price as a market reference, and the level of manipulation resistance desired.
59+
60+
### (Optional) zero percentage steps
61+
It's possible to configure the schedule to have multiple steps with a 0% issuance rate.
62+
63+
If included in the beginning of the schedule, it functions as a **pre-bid** phase where bidders can bid before tokens start being sold. This is beneficial for large auctions as it reduces the chance that tokens are left unsold in earlier blocks of the auction.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"label": "Advanced",
3+
"position": 6,
4+
"collapsed": true
5+
}

0 commit comments

Comments
 (0)