Docs

Merge

Two Snowmen on the same pair become one. The rules the contract enforces, and why.

Rules

RuleReason
same collectionLP positions on different pools cannot be combined
caller owns bothno approvals, no third-party merges
survivor keeps id, gene, historygeneration = max + 1, merges = a + b + 1
donor burned, id never reusablea reminted id would inherit the old account

The sweep

The collection takes custody of the donor NFT at the top of the call, which makes it the account's owner and therefore a valid signer for execute. It then moves every listed ERC-20, every listed ERC-721 position and any native ETH to the survivor's account, and burns the donor.

merge
merge(survivor, donor)                                  // native ETH only
merge(survivor, donor, address[] erc20s, NftPosition[] positions)

for each asset: before = balance(survivor)
                donorAccount.execute(transfer)
                require(balance(survivor) - before == expected)  // not the execute bool
Assets not in the sweep list are stranded when the donor burns. The site builds the list from the indexer so this does not happen by accident; if you call the contract directly, list everything.

ERC-6551 footguns

An uninitialised proxy account's execute returns success while moving nothing, so the contract verifies by post-transfer balance and reverts with PhantomTransfer. Positions move with transferFrom, not safeTransferFrom, because a receiver hook on the account could run arbitrary code mid-merge; the ownerOf check proves delivery anyway. Sweeping the collection itself is refused to avoid ownership cycles, which brick an account rather than merely lock it.