Platform: Code4rena
Start Date: 17/03/2022
End Date: 19/03/2022
Period: 3 days
Status: Completed
Pot Size: $30,000 USDC
Participants: 43
Reporter: liveactionllama
Judge: gzeon
Id: 100
League: ETH
kirk-baird | 1/43 | $6,790.00 | 2 | 1 | 1 | 0 | 0 | - | 0 | 0 |
cmichel | 2/43 | $4,453.58 | 4 | 2 | 0 | 1 | 1 | - | 0 | 0 |
WatchPug | 3/43 | $2,677.08 | 4 | 1 | 0 | 1 | 1 | - | - | 0 |
leastwood | 4/43 | $2,416.96 | 3 | 1 | 0 | 1 | 0 | - | 0 | 0 |
csanuragjain | 5/43 | $2,122.73 | 2 | 0 | 0 | 1 | 1 | - | 0 | 0 |
Ruhum | 6/43 | $2,073.31 | 2 | 0 | 0 | 1 | 1 | - | 0 | 0 |
IllIllI | 7/43 | $1,976.43 | 3 | 1 | 0 | 0 | 0 | - | - | 0 |
GreyArt | 8/43 | $1,384.91 | 4 | 1 | 0 | 1 | 0 | - | - | 0 |
rayn | 9/43 | $1,187.27 | 4 | 1 | 0 | 1 | 0 | - | - | 0 |
CertoraInc | 10/43 | $638.45 | 3 | 1 | 0 | 0 | 0 | - | - | 0 |
Auditor per page
prePO is a decentralized trading platform allowing anyone to speculate on the valuation of any pre-IPO company or pre-token crypto project.
prePO markets function similarly to scalar prediction markets, with traders speculating (by going long or short) on the fully-diluted market capitalization that a pre-IPO company or pre-token crypto project will have when it eventually goes public.
Recommended reading:
Recommended viewing:
All the contracts in this section are to be reviewed. Any contracts not in this list are to be ignored for this contest.
AccountAccessController.sol
+ IAccountAccessController.sol
(87 + 18 sloc)CollateralDepositRecord.sol
+ ICollateralDepositRecord.sol
(104 + 16 sloc)DepositHook.sol
+ IHook.sol
(53 + 10 sloc)AccountAccessController.sol
, CollateralDepositRecord.sol
WithdrawHook.sol
+ IHook.sol
(53 + 10 sloc)CollateralDepositRecord.sol
SingleStrategyController.sol
+ IStrategyController.sol
+ IStrategy.sol
(79 + 19 + 10 sloc)IStrategy.sol
Collateral.sol
+ ICollateral.sol
(276 + 59 sloc)SingleStrategyController.sol
, DepositHook.sol
, WithdrawHook.sol
LongShortToken.sol
+ ILongShortToken.sol
(12 + 7 sloc)PrePOMarket.sol
+ IPrePOMarket.sol
(223 + 46 sloc)Collateral.sol
, 2x LongShortToken.sol
PrePOMarketFactory.sol
+ IPrePOMarketFactory.sol
(107 + 28 sloc)yarn hardhat node
will launch a JSON-RPC node locally on localhost:8545
.
Running yarn hardhat node
without the --no-deploy
tag will also execute everything defined in the deploy
folder.
It is advised to instead run deployments separately using yarn hardhat deploy
with specific --tags
to ensure you only
deploy what you need, e.g. yarn hardhat deploy --network 'localhost' --tags 'Collateral'
Because our scripts use hardhat-upgrades
to deploy our upgradeable contracts, they are not managed by hardhat-deploy
.
Upgradeable deployment addresses are kept track of separately in a local .env
file.
hardhat-deploy
will automatically call deployment scripts for any dependencies of a specified tag
.
Per the tag dependency tree below, specifying PrePOMarketFactory
under --tags
, will deploy the entire PrePO core stack.
A mock strategy can be deployed as well for testing purposes with the MockStrategy
tag.
CollateralDepositRecord AccountAccessController ^ ^ ^ | | | | | | WithdrawHook DepositHook-------------+ SingleStrategyController BaseToken ^ ^ ^ ^ | | | | | | | | +--------------+-----------------------Collateral------------+------------------+ ^ | | +---------+---------+ | | | | | | PrePOMarketFactory MockStrategy (optional)
The Collateral
vault, consisting of AccountAccessController.sol
, Collateral.sol
, CollateralDepositRecord.sol
, DepositHook.sol
, and WithdrawHook.sol
, has the following features to protect itself from malicious actors:
initiateWithdrawal(uint256 amount)
. The number of blocks until a request expires is settable by the vault owner()
. This is mainly for mitigating the feasibility of a flash loan attack.BaseToken
amount deposited by each account is kept track of by CollateralDepositRecord.sol
.Collateral
vault. Allowed and Blocked accounts are managed by AccountAccessController.sol
.Collateral
vault can disable deposit
and withdraw
in the case of an emergency.onlyOwner
functions will be executed by a timelocked executor smart contract (out of audit scope), which itself will only be callable by the DAO multisig.The following are potential areas of concern which could benefit from focus during the audit:
Collateral.sol
and SingleStrategyController.sol
that could result in a malicious actor being able to mint/redeem an outsized amount of shares/BaseToken
. The actual Strategy
to be used in production is not under the scope of this review and is still in development, so you will have to analyze the security of our vault-strategy architecture without a particular underlying Strategy
. For our testnet, we are using a mock Strategy
(MockStrategy.sol
).AccountAccessController.sol
or DepositHook.sol
into allowing it to deposit assets into Collateral.sol
.PrePOMarket.sol
will be initialized with its own parameters, dictating the terms for minting/redeeming positions within the market. We want to ensure these parameters cannot be bypassed (i.e. A trader minting positions after expiry or redeeming their position for an outsized amount of Collateral
).Ownable.sol
to prevent anyone besides owner()
from modifying sensitive parameters. We want to be sure this restriction cannot be bypassed and want to be alerted to any sensitive parameters in our contracts that are unprotected.We are aware the following state variables in PrePOMarket.sol
:
_mintingFee
, _redemptionFee
, _expiryTime
, _floorValuation
, _ceilingValuation
, _floorLongPrice
, _ceilingLongPrice
, _finalLongPrice
, _publicMinting
and constants:
MAX_PRICE
, FEE_DENOMINATOR
, FEE_LIMIT
could use smaller types to save on deployment/initialization costs via struct packing. We will not be awarding optimizations found related to condensing types for these variables.
Collateral.sol
and PrePOMarketFactory.sol
are the only upgradeable contracts. If we ever need to update PrePOMarket.sol
to add new features for future markets, we can upgrade PrePOMarketFactory.sol
with the new PrePOMarket.sol
implementation. In production, our upgradeable contracts will be deployed using OpenZeppelin’s Hardhat Upgrades API.
Any gas optimization suggestions should focus on reducing costs for functions that will be called many times. If an optimization increases the deployment cost for a contract, the savings provided by that optimization over a reasonable timeframe should outweigh the increased deployment cost.
Functions that would likely be called often are listed below:
isAccountAllowed
, isAccountBlocked
, allowAccounts
, blockAccounts
deposit
, initiateWithdrawal
, _processDelayedWithdrawal
, withdraw
recordDeposit
, recordWithdrawal
mintLongShortTokens
, redeem
createMarket
deposit
, withdraw