Build
Locks and vesting
Launch liquidity is locked forever by contracts with no owner. Any other CL position can be time-locked, any token can be locked or vested, and every lock is public.
Launch liquidity
Every launch through the kit hands its pool position to a locker in the same transaction: GullyCoreLPLocker for a CL pool, GullyCoreBinLPLocker for a Bin pool. Neither has an owner, a withdraw function, a pause or an upgrade path. The principal never leaves.
The Bin locker tracks each bin's principal and only ever removes growth above it as fees. Tokens a buyer paid into a launch bin are principal and stay.
Who collects the fees
What a locked position earns is collected by a permissionless collectFees call and split by the lock's terms, frozen when the lock was made. The split is between the creator, the launchpad the launch came through (where there is one) and the protocol. On pools a builder creates, Gully takes a flat 0.30% of every trade and nothing else. Gully's own apps follow separate terms. See Fees.
Each party then claims its own credit. A creator does it on Portfolio. A creator can hand the creator slot to another address in two steps. Tokens sent to a locker by mistake can be swept by anyone, to the protocol.
Lock any position
GullyCorePositionLock time-locks a CL position NFT until a date you choose. Open Lock liquidity.
- Until the unlock date nobody can withdraw the position, not the lock's owner and not Gully Core.
- The lock's owner can collect the position's fees while it is locked, and extend the date (never shorten it).
- The lock can be handed to another owner in two steps.
- After the date, the owner withdraws the NFT.
From code, the steps are: read which CLPositionManager the lock accepts (never assume), check the unlock date is valid, approve the lock for this one NFT (never setApprovalForAll), then lock it. The fee is read live. The value sent is the larger of the fee and the announced fee, and the surplus is refunded. The SDK builds these calls. Not on npm yet: it runs from a checkout of the repository. See SDK.
A position on a pool whose hook can refuse liquidity removal may have its fee collection blocked by that hook. The principal is never affected.
The Locked by Gully Core badge
Every lock is listed on the public Locker, no wallet needed, with what is locked, until when, and the share of the pool's active liquidity it is. A project can embed a live badge on its own site.
Vesting and token locks
Lock any ERC-20 or the native coin until a date, or vest it in a straight line after a cliff. Nobody can end a lock early, including Gully Core.
Open Distribute. A lock is held by GullyCoreTokenLock and has:
| Field | Meaning |
|---|---|
| Currency and amount | Any ERC-20, or the native coin |
| Beneficiary | The address that may claim |
| Start, cliff, end | Nothing vests before the cliff. From the cliff the vested amount follows the straight line from start to end. Everything is vested at the end |
| Time-lock | Start, cliff and end at the same moment: all of it unlocks at once |
From code, a vesting schedule is built from a start, a cliff length and a duration (for example nothing for six months, then linear to month 24). The amount is parsed exactly in the token's decimals. An ERC-20 needs an exact approval for the amount first, then the lock call, where the value sent is the fee only. For the native coin the amount is added to the value.
Claim and release
claim(lockId, to): the beneficiary takes what has vested, to any address.release(lockId): pays what has vested to the lock's current beneficiary. Anyone may call it when the beneficiary is a plain wallet or aGullyCoreSplit. A beneficiary that is any other contract may only release for itself.- The beneficiary can hand the lock to another address in two steps.
- Every lock is public on the Locker.
Fee
Locking through a launch costs nothing extra. Time-locking a position with GullyCorePositionLock, or locking tokens with GullyCoreTokenLock, costs one flat fee in the native coin per lock. The contract charges it itself, so the app, the SDK and a direct call all pay the same. Governance sets it inside an immutable cap of ten times the starting value. An increase takes effect only after a 7-day notice, a decrease at once. Fees are paid out only to the governance Safe.
The exact amount is read from the contract (feeWei(), maxFeeWei(), feeNoticeSeconds()).
Wrong or missing? Tell us at @Gully_Labs.