# Bufficorn Trait Swapping Architecture ## Database Schema **Swap Schema** | field | type | | ---------------------- | ------- | | id | MongoId | | swapInitiator | Text | | swapInitiatorBufficorn | Number | | swapInitiatedTimestamp | Date | | swapInitiateSporkTx | Text | | swapExecutor | Text | | swapExecutorBufficorn | Number | | swapExecutedTimestamp | Date | | swapExecutedSporkTx | Text | | traitsToSwap | [Enum] | | stakeStatus | Enum | ## Escrow Contract Made an escrow contract gist for ideation. [ Bufficorn Trait Swapper Escrow ](https://gist.github.com/manolingam/90a66b02fae1219b963493c3c39587ef) ### Go Grazing: 1. list bufficorns the wallet owns (using alchemy api) 2. interact with grazing contract & go grazing ### Gone Home: 1. list bufficorns the wallet has put for grazing (using subgraph) _validations before going home:_ _- check if min grazing period over_ 2. interact with grazing contract & gone home ### Trait Swapping: **As a swap initiator:** 1. choose my bufficorn that's grazing to be trait swapped 3. enter token id of the other bufficorn to be trait swapped 4. choose traits to be swapped _validations before initiating swap:_ _- check if the other bufficorn is grazing (using grazing contract)_ _- check if the initiator bufficorn is locked in any other swap (using escrow contract)_ _- check if the executor bufficorn is locked in any other swap (using escrow contract)_ _- check if initiator wallet has enough spork token balance_ 4. create a swap record (using database) 5. with the swap id from previous step, deposit spork token (interact with the initiateTraitSwap() in escrow contract) 6. provide the swap id to the other party (swap executor) to execute. **As a swap executor:** 1. Enter the swap id received from swap initiator. _validations before executing the swap:_ _- check if the swap id is valid & the stake status(using database)_ _- check if the swap window over (using database)_ _- check if the executor bufficorn is locked in any other swap (using escrow contract)_ _- check if executor wallet has enough spork token balance_ 2. with the swap id, deposit spork token (interact with the executeTraitSwap() in escrow contract) 3. on successful tx, update the corresponding swap info in the database using the swap id. **Withdraw stake** If the executor fails to finish the swap, the initiator can use the withdrawSporkStake() function in escrow contract to get back his stake. 1. Enter swap id to withdraw stake. _validations before withdrawing the stake:_ _- check if the swap id is valid & the stake status(using database)_ _- check if the swap window over (using database)_ _- check if the requesting address is a swap initiator for the corresponding swap_ _- check if the escrow contract has enough spork balance to send back the stake_ 2. return spork token & on successful tx, update the corresponding stake info in the database using the swap id.