Create Auction
This guide will provide steps for creating an auction in the Axis system through direct integration with the contracts. It will break the components into different steps, to ease understanding. This particular guide will use the EncryptedMarginalPrice auction module.
Setup
First, we define a variable for the AuctionHouse. The address used here is a testnet address. However, the current addresses for both testnet and production deployments can be obtained from the Contract Addresses page.
// Define the deployed AuctionHouse
IAuctionHouse auctionHouse = IAuctionHouse(_auctionHouse);
Note that the address used for the AuctionHouse corresponds to the auction type used. An Atomic auction type would use the AtomicAuctionHouse, and a Batch auction type would use the BatchAuctionHouse. However, for the purposes of auction creation, the IAuctionHouse
interface can be used.
The next step is to set up the tokens that will be used in the auction. In this example, mock ERC20
contracts are deployed to make minting simple.
// Define the tokens used in the auction
MockERC20 quoteToken = _getQuoteToken();
MockERC20 baseToken = _getBaseToken();
Inputs
In this section, we prepare the inputs to the auction create function.
Routing Parameters
The routing parameters are used by the AuctionHouse contract to define the configuration related to the auction format, tokens, curator, callbacks and derivative. These parameters are kept separate from the auction parameters, which are used by the auction module defined in the auctionType
property.
// Define the auction routing parameters
IAuctionHouse.RoutingParams memory routingParams = IAuctionHouse.RoutingParams({
auctionType: toKeycode("EMPA"),
baseToken: address(baseToken),
quoteToken: address(quoteToken),
curator: address(0), // Optional
referrerFee: 0, // Optional
callbacks: ICallback(address(0)), // Optional
callbackData: abi.encode(""), // Optional
derivativeType: toKeycode(""), // Optional
derivativeParams: abi.encode(""), // Optional
wrapDerivative: false
});
The code above configures an auction with the following:
- Auction format is EncryptedMarginalPrice (using the
Keycode
of the module,EMPA
) - Uses the base and quote tokens that were deployed earlier in this guide
- No curator is defined
- No callback contract is defined
- No derivative is defined
Auction Parameters
Auction parameters are used by the respective auction module to configure the auction lot.
There are 4 standard configuration parameters across all auction modules:
// Define the auction parameters
uint48 start = uint48(block.timestamp + 1 days);
uint48 duration = uint48(3 days);
bool capacityInQuote = false;
uint256 capacity = 10e18;
This would result in an auction with the following features:
- Commencing one day after the block in which the auction is created
- The auction will last for 3 days
- Has a capacity of 10 base tokens
Auction Module Parameters
Each auction module will likely have implementation-specific parameters that are used. The EncryptedMarginalPrice auction module takes parameters that are defined in the struct IEncryptedMarginalPrice.AuctionDataParams
.
One of these parameters is the public key for the auction, which is used to encrypt bids. In this example script, the user sets the AUCTION_PRIVATE_KEY
environment variable to be an integer value representing the auction's private key. The script reads that environment variable and generates a public key using the ECIES library.
The auction private key should only be handled in an off-chain script, otherwise third-parties would be able to decrypt any submitted bids.
// Calculate the auction public key
Point memory auctionPublicKey = ECIES.calcPubKey(
Point(1, 2),
vm.envUint("AUCTION_PRIVATE_KEY")
);
Next, we assemble the parameters for the EncryptedMarginalPrice auction module:
// Define the auction module parameters
IEncryptedMarginalPrice.AuctionDataParams memory empParams = IEncryptedMarginalPrice
.AuctionDataParams({
minPrice: 1e18, // 1 quote token per base token
minFillPercent: 10_000, // 10%
minBidSize: 1e18, // 1 quote token
publicKey: auctionPublicKey
});
This defines an EncryptedMarginalPrice auction with the following features:
- Bids must have a minimum price of 1 quote token per base token in order to be considered for settlement
- 10% of the capacity (defined in the Auction Parameters section) must be filled in order for the auction to settle
- Each bid must have an amount in of at least 1 quote token in order to be accepted
Combining Auction Parameters
We then combine the standard auction parameters with the module-specific parameters:
IAuction.AuctionParams memory auctionParams = IAuction.AuctionParams({
start: start,
duration: duration,
capacityInQuote: capacityInQuote,
capacity: capacity,
implParams: abi.encode(empParams)
});
The implParams
property of the struct encodes the module-specific parameters. This enables auction modules to specify different configuration options without being bound to a specific structure.
Token Funding
As the configured auction is a batch auction, the AuctionHouse will pre-fund the auction at the time of creation. For this reason, we need to ensure that the seller has the required balance of base tokens (the capacity). The seller also needs to approve spending of the tokens by the AuctionHouse.
// Mint base tokens to the seller
baseToken.mint(_SELLER, capacity);
// The AuctionHouse will pull base tokens from the seller upon auction creation,
// so approve the auction capacity
vm.prank(_SELLER);
baseToken.approve(address(auctionHouse), capacity);
Contract Call
The Axis frontend links additional auction information (such as a title, icons and description) to the auction using an IPFS hash, which is passed into the AuctionHouse and emitted in an event. It is not required for this example, so we define it as an empty string.
// Define the IPFS hash for additional information
string memory ipfsHash = "";
Lastly, we create the auction. The caller of the contract is considered the seller, so we use vm.prank
to assume the role of the seller in the example script.
// Create the auction
vm.prank(_SELLER);
uint96 lotId = auctionHouse.auction(routingParams, auctionParams, ipfsHash);
console2.log("Created auction with lot ID:", lotId);
Source Code
The source code for the guide is located in the create-auction.s.sol file.