Skip to content

Commit bdff97d

Browse files
committed
feat: added mint auth lib
1 parent 3efec93 commit bdff97d

2 files changed

Lines changed: 400 additions & 0 deletions

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.20;
3+
4+
import {Lib128Fields} from "./Lib128Fields.sol";
5+
6+
/// @title LibMintAuth
7+
/// @notice Library for gas-efficient storage and manipulation of PT and YT mint authorization data.
8+
/// @dev Implements packed storage where PT and YT mint authorization values are stored together in single uint256 slots:
9+
/// - Lower 128 bits: PT (Principal Token) mint authorization
10+
/// - Upper 128 bits: YT (Yield Token) mint authorization
11+
/// This packing reduces storage costs and enables atomic updates of both authorization values.
12+
/// The actual bit manipulation and storage operations are delegated to {Lib128Fields},
13+
/// which provides gas-optimized assembly implementations for reading and writing packed uint128 fields.
14+
/// Used to track minting authorizations for addresses across the dual-token system.
15+
library LibMintAuth {
16+
using Lib128Fields for uint256;
17+
18+
/// @dev Seed used to derive mint authorization storage slots for each minter address.
19+
/// The mint auth slot for a `minter` is computed as:
20+
/// ```
21+
/// mstore(0x0c, _MINT_AUTH_SLOT_SEED)
22+
/// mstore(0x00, minter)
23+
/// let mintAuthSlot := keccak256(0x0c, 0x20)
24+
/// ```
25+
/// Each slot contains: [YT mint auth (upper 128 bits) | PT mint auth (lower 128 bits)]
26+
uint256 internal constant _MINT_AUTH_SLOT_SEED = 0x08395086;
27+
28+
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
29+
/* SLOT COMPUTATION */
30+
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
31+
32+
/// @notice Computes the storage slot for a minter's PT and YT mint authorizations.
33+
/// @dev Uses keccak256 to derive a unique storage slot from the mint auth seed and minter address.
34+
/// The resulting slot contains packed PT (lower 128 bits) and YT (upper 128 bits) mint authorizations.
35+
///
36+
/// Slot Derivation:
37+
/// 1. Place _MINT_AUTH_SLOT_SEED at memory position 0x0c
38+
/// 2. Place minter address at memory position 0x00
39+
/// 3. Hash 0x20 bytes starting from 0x0c
40+
///
41+
/// This approach ensures deterministic, collision-resistant storage locations for each minter.
42+
/// @param minter The address to compute the mint authorization slot for
43+
/// @return slot The storage slot containing the packed PT and YT mint authorizations
44+
function mintAuthSlot(address minter) internal pure returns (uint256 slot) {
45+
/// @solidity memory-safe-assembly
46+
assembly {
47+
mstore(0x0c, _MINT_AUTH_SLOT_SEED)
48+
mstore(0x00, minter)
49+
slot := keccak256(0x0c, 0x20)
50+
}
51+
}
52+
53+
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
54+
/* MINT AUTHORIZATION */
55+
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
56+
57+
/// @notice Returns both PT and YT mint authorizations for a given minter in a single read.
58+
/// @dev Computes the storage slot using keccak256 and reads the packed mint authorizations using {Lib128Fields.fromSlot}.
59+
/// Gas-efficient single storage read. No validation is performed; the caller must ensure proper usage.
60+
/// @param minter The address to query mint authorizations for
61+
/// @return ptMintAuth The PT mint authorization (lower 128 bits) as uint128
62+
/// @return ytMintAuth The YT mint authorization (upper 128 bits) as uint128
63+
function mintAuth(address minter) internal view returns (uint128 ptMintAuth, uint128 ytMintAuth) {
64+
(ptMintAuth, ytMintAuth) = mintAuthSlot(minter).fromSlot();
65+
}
66+
67+
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
68+
/* UPDATES */
69+
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
70+
71+
/// @notice Updates both PT and YT mint authorizations for a given minter atomically.
72+
/// @dev Computes the storage slot using keccak256, packs both authorizations into a single uint256 using
73+
/// {Lib128Fields.write}, and writes to storage. More gas-efficient than separate writes.
74+
/// No validation is performed; the caller must ensure values fit in uint128.
75+
/// @param minter The address whose mint authorizations to update
76+
/// @param ptMintAuth The new PT mint authorization (stored in lower 128 bits)
77+
/// @param ytMintAuth The new YT mint authorization (stored in upper 128 bits)
78+
function updateMintAuth(address minter, uint128 ptMintAuth, uint128 ytMintAuth) internal {
79+
mintAuthSlot(minter).write(ptMintAuth, ytMintAuth);
80+
}
81+
}

0 commit comments

Comments
 (0)