Ring-buffer locks paper
The 16-slot quarterly ring-buffer time-lock primitive, with O(1) reads and writes.
The core result
Tracking N concurrent timed locks naively requires O(N) iteration on every read. The ring-buffer construction reduces this to O(1) by exploiting the algebraic identity:
where:
Dis the total locked depth.Q_iis the prefix-sum of token-seconds in sloti.Tis the total locked balance.tis the current time.pis the permanent-locked balance.Lis the elapsed time on the permanent component.
The formula evaluates in constant time regardless of how many slots are populated. The ring buffer lets the protocol amortise lock additions across slots without ever iterating over them.
Why 16 slots and quarters
- 16 slots × 91.3125 days = 1,461 days = 4 Julian years. The exact slot length comes from
MAX_LOCK_TERM = MONTH × 3withMONTH = YEAR / 12andYEAR = CENTURY / 100 = 365.25 days. Enough horizon to cover most user use cases. - Quarterly granularity. Coarser than monthly (saves storage), finer than yearly (gives meaningful flexibility).
- Power-of-2 slot count. Cleaner modular arithmetic for the ring index.
Self-healing
When a new lock writes to a slot whose existing entry has already expired, the protocol automatically clears the expired entry. No manual cleanup is required from the user. The contract operates correctly even if expired entries linger.
Why not Heap or sorted list?
Both alternatives have O(log N) cost per operation, with worse constants and more complex code. The ring buffer is conceptually simpler and gas-cheaper for the actual access patterns.
Where to find the paper
- PDF:
banq-lck.pdf(latest release) - Unified bundle:
banq-all.pdf— this paper is one of two engineering primitives in Part II.
Where to go next
- Timed vs permanent — the user-facing version
- Bonus and malus — what the lock pays