# Relay Guild: Fee Collector MVP Contract ## Statement of Work This proposal outlines the work required to implement an MVP contract for the [Aestus](https://aestus.live/) [MEV-Boost relay](https://www.relayscan.io/) team to charge service fees to participating block builders. [A preliminary scope of the problem space can be found here.](https://hackmd.io/@austonst-aestus/r1dQPeCl6) ## Scope The project focuses on writing an initial fee collector contract MVP that allows Aestus MEV-Boost relay guild to charge registered block builders a small fee from their deposited collateral. ### Project Requirements The following is a list of general requirements. Actual contract properties, function implementation and contract events may differ on the go. - A fee collector contract should have the following properties: - A mapping of builders ETH address to builder props: - pubKeys: bytes[][48] // builder can register n pubKeys - active: bool // status - totalBalance: uint256 // total builder deposited collateral - withdrawAtNextReconciliation: bool // builder signals to withdraw remaining collateral at next reconciliation - withdrawableBalance: uint256 // builder available collateral to withdraw - Service fee parameters: - currentFee: uint256 // current service fee (<= 1e6 (100%)) until next reconciliation - nextEpochFee: uint256 // useful for advanced notice to builders - nextReconciliationBlock: // block from where the next reconciliation can be executed - lastReconciationBlock // keeps track of block when last reconciliation took place - Guild Safe multisig address - Owner address - A new fee collector contract should require a Safe multisig and a owner role addresses as parameters. - Would be good to also provide initial service fee parameters. - Service fee parameters should have default values during deployment. - MEV-Boost Relay Fee collector contract aims to charge a small fee (0.5% block value) on a regular schedule to participating builders. - Service fee should be updated by the owner role at any time - MEV-Boost Guild accepts new builders onto their relay by requesting their BLS public key (BLS12-381 48 bytes length), ETH address and **an optional** minimum ETH-denominated upfront deposit or collateral to become eligible for submitting blocks to proposing validators. - Validate pubkeys aren't registered to more than one builder - New builders can be registered by themselves or by the owner - Builders should be able to call a `deposit` function at any time to add collateral for their operations. - Builders should be able to update (add/remove) their pubKeys list - Registered builders should be able to withdraw any remaining collateral **only after** the next **reconciliation** is executed. - They sould be able to call a `withdrawAtNextReconciliation()` function so set `withdrawAtNextReconciliation=true` - On a regular schedule (e.g. weekly, 1000 slot window) the Guild uses an off-chain accounting system to calculate accumulated fees on a block-by-block basis. This data is then fed to the contact to **reconcile** builder collateral balances and forward charged fees to the Guild multisig (Safe), while remaining balances from builders marked as `withdrawAtNextReconciliation=rue` should be accounted as withdrawable. - Builders with no collateral should be marked as `active = false`. - Builders then should be able to call a withdraw function (it's better to implement a. Pull over push pattern) - ~~allow builders to send a flag if they want to fully exit the guild, if so, their record is deleted from the registry.~~ - ~~Instead of sending a `reconcileSlot` parameter, I recommend sending a nextReconciliationBlock to update service fee paramters as follows:~~ - ~~`currentFee = nextEpochFee`~~ - ~~`nextReconciliationBlock = _nextReconciliationBlock`~~ - The `reconcile` function should be callable **only** after `tx.block > nextReconciliationBlock` - **this kind modifier should be considered in V2** - Contract owner should be able to call `setServiceFee` to update `currentFee`, `nextEpochFee` and `nextReconciliationBlock` - ~~I recommend just sending `nextEpochFee` and `nextReconciliationBlock` so this can be called only if you really looking to update the fee, otherwise `currentFee` and `nextReconciliationBlock` would be updated in the last reconciliation call.~~ - Contract should emit the neccesary events to allow the guild to fetch the data structures defined in their spec document (list of builders, deposts, reconciliation events). - Contract should allow room to plug in governance in the future (accountability of any action to be performed by Ownable role). - Contract should be upgradable. ### Nice to have (probably not included in the first MVP) - Verify BLS public key ownership at the contact level (currently Solidity doesn't support BLS signature natively) - Still need to dig into this https://ethresear.ch/t/bls-signatures-in-solidity/7919 # Deliverables 1. **Contract repository**: a (**private) repository using Foundry 3. **Comprehensive Documentation**: contracts will be fully covered with natspec documentation 4. **Tested Solution**: A complete suite of unit tests covering the MVP features. # Process 1. **Initial Review**: Begin with a comprehensive review of the current spec to understand MVP requirements. 2. **Development**: Implement the changes as outlined in the scope. 3. **Testing**: After development, test the system using the provided examples and any additional test cases deemed necessary. 4. **Documentation**: write detailed documentation and how to use the project repository. 5. **Feedback & Revisions**: Seek feedback on the implementation and make any necessary revisions. # Proposal | Phases | Description | ETA | | -------- | -------- | -------- | | **Review** | Comprehensive review of the current spec & proposal. | 0.5 day | | **Development** | Implement contract logic. | 1.5 day | | **Testing** | Thoroughly test the contract using provided examples. | 1.5 day | | **Documentation** | Write necessary documentation. | 0.5 day | | **Feedback & Revisions** | Address feedback and make necessary revisions. | 1 day | | **Total** | | **2.5 ETH** | **Total Estimated Time**: 5 days ## Estimated Time - 40 Hours ## Payout - 2.5 ETH (Ethereum/Optimism)