Skip to content

Commit

Permalink
add AllocatorLogic and RegistrationLogic
Browse files Browse the repository at this point in the history
  • Loading branch information
0age committed Oct 31, 2024
1 parent efd14f4 commit 0fbcc2d
Show file tree
Hide file tree
Showing 6 changed files with 272 additions and 144 deletions.
54 changes: 27 additions & 27 deletions snapshots/TheCompactTest.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{
"basicTransfer": "56861",
"basicWithdrawal": "59819",
"batchClaim": "111831",
"batchClaimRegisteredWithDeposit": "111831",
"batchClaimRegisteredWithDepositWithWitness": "112593",
"batchClaimWithWitness": "112587",
"basicTransfer": "56858",
"basicWithdrawal": "59816",
"batchClaim": "111828",
"batchClaimRegisteredWithDeposit": "111828",
"batchClaimRegisteredWithDepositWithWitness": "112590",
"batchClaimWithWitness": "112584",
"batchDepositAndRegisterViaPermit2": "221900",
"batchDepositAndRegisterWithWitnessViaPermit2": "221878",
"batchTransfer": "81539",
"batchWithdrawal": "99954",
"claim": "56978",
"claimAndWithdraw": "73269",
"claimWithWitness": "59443",
"batchTransfer": "81536",
"batchWithdrawal": "99951",
"claim": "56975",
"claimAndWithdraw": "73266",
"claimWithWitness": "59440",
"depositAndRegisterViaPermit2": "124270",
"depositBatchSingleERC20": "67868",
"depositBatchSingleNative": "28171",
Expand All @@ -22,21 +22,21 @@
"depositERC20ViaPermit2AndURI": "98312",
"depositETHAndURI": "26777",
"depositETHBasic": "28384",
"qualifiedBatchClaim": "113249",
"qualifiedBatchClaimWithWitness": "112713",
"qualifiedClaim": "60237",
"qualifiedClaimWithWitness": "58777",
"qualifiedSplitBatchClaim": "140937",
"qualifiedSplitBatchClaimWithWitness": "140929",
"qualifiedSplitClaim": "86524",
"qualifiedSplitClaimWithWitness": "86890",
"qualifiedBatchClaim": "113246",
"qualifiedBatchClaimWithWitness": "112710",
"qualifiedClaim": "60234",
"qualifiedClaimWithWitness": "58774",
"qualifiedSplitBatchClaim": "140934",
"qualifiedSplitBatchClaimWithWitness": "140926",
"qualifiedSplitClaim": "86521",
"qualifiedSplitClaimWithWitness": "86887",
"register": "25379",
"splitBatchClaim": "140399",
"splitBatchClaimWithWitness": "140363",
"splitBatchTransfer": "110614",
"splitBatchWithdrawal": "139822",
"splitClaim": "86447",
"splitClaimWithWitness": "85928",
"splitTransfer": "82751",
"splitWithdrawal": "93705"
"splitBatchClaim": "140396",
"splitBatchClaimWithWitness": "140360",
"splitBatchTransfer": "110611",
"splitBatchWithdrawal": "139819",
"splitClaim": "86444",
"splitClaimWithWitness": "85925",
"splitTransfer": "82748",
"splitWithdrawal": "93702"
}
3 changes: 2 additions & 1 deletion src/TheCompact.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Scope } from "./types/Scope.sol";
import { ResetPeriod } from "./types/ResetPeriod.sol";
import { ForcedWithdrawalStatus } from "./types/ForcedWithdrawalStatus.sol";

import { AllocatorLogic } from "./lib/AllocatorLogic.sol";
import { ClaimProcessor } from "./lib/ClaimProcessor.sol";
import { Extsload } from "./lib/Extsload.sol";

Expand All @@ -25,7 +26,7 @@ import { ISignatureTransfer } from "permit2/src/interfaces/ISignatureTransfer.so
* formation and mediation of reusable "resource locks."
* This contract has not yet been properly tested, audited, or reviewed.
*/
contract TheCompact is ITheCompact, ClaimProcessor, ERC6909, Extsload {
contract TheCompact is ITheCompact, AllocatorLogic, ClaimProcessor, ERC6909, Extsload {
function deposit(address allocator) external payable returns (uint256) {
return _performBasicNativeTokenDeposit(allocator);
}
Expand Down
97 changes: 97 additions & 0 deletions src/lib/AllocatorLogic.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;

import { BatchTransfer, SplitBatchTransfer } from "../types/BatchClaims.sol";
import { BasicTransfer, SplitTransfer } from "../types/Claims.sol";
import { CompactCategory } from "../types/CompactCategory.sol";
import { SplitComponent, TransferComponent, SplitByIdComponent } from "../types/Components.sol";
import { ForcedWithdrawalStatus } from "../types/ForcedWithdrawalStatus.sol";
import { Lock } from "../types/Lock.sol";
import { ResetPeriod } from "../types/ResetPeriod.sol";
import { Scope } from "../types/Scope.sol";

import { ConsumerLib } from "./ConsumerLib.sol";
import { EfficiencyLib } from "./EfficiencyLib.sol";
import { FunctionCastLib } from "./FunctionCastLib.sol";
import { HashLib } from "./HashLib.sol";
import { IdLib } from "./IdLib.sol";
import { MetadataRenderer } from "./MetadataRenderer.sol";
import { ValidityLib } from "./ValidityLib.sol";

import { SafeTransferLib } from "solady/utils/SafeTransferLib.sol";
import { Tstorish } from "tstorish/Tstorish.sol";
import { ISignatureTransfer } from "permit2/src/interfaces/ISignatureTransfer.sol";

contract AllocatorLogic {
using HashLib for address;
using HashLib for bytes32;
using HashLib for uint256;
using HashLib for BasicTransfer;
using HashLib for SplitTransfer;
using HashLib for BatchTransfer;
using HashLib for SplitBatchTransfer;
using IdLib for uint96;
using IdLib for uint256;
using IdLib for address;
using IdLib for Lock;
using IdLib for ResetPeriod;
using SafeTransferLib for address;
using ConsumerLib for uint256;
using EfficiencyLib for bool;
using EfficiencyLib for bytes32;
using EfficiencyLib for uint256;
using ValidityLib for address;
using ValidityLib for uint96;
using ValidityLib for uint256;
using ValidityLib for bytes32;
using FunctionCastLib for function(bytes32, address, BasicTransfer calldata) internal;

function _consume(uint256[] calldata nonces) internal returns (bool) {
// NOTE: this may not be necessary, consider removing
msg.sender.usingAllocatorId().mustHaveARegisteredAllocator();

unchecked {
uint256 i;

assembly ("memory-safe") {
i := nonces.offset
}

uint256 end = i + (nonces.length << 5);
uint256 nonce;
for (; i < end; i += 0x20) {
assembly ("memory-safe") {
nonce := calldataload(i)
}
nonce.consumeNonceAsAllocator(msg.sender);
}
}

return true;
}

function _registerAllocator(address allocator, bytes calldata proof) internal returns (uint96 allocatorId) {
allocator = uint256(uint160(allocator)).asSanitizedAddress();
if (!allocator.canBeRegistered(proof)) {
assembly ("memory-safe") {
// revert InvalidRegistrationProof(allocator)
mstore(0, 0x4e7f492b)
mstore(0x20, allocator)
revert(0x1c, 0x24)
}
}

allocatorId = allocator.register();
}

function _hasConsumedAllocatorNonce(uint256 nonce, address allocator) internal view returns (bool) {
return allocator.hasConsumedAllocatorNonce(nonce);
}

function _getLockDetails(uint256 id) internal view returns (address token, address allocator, ResetPeriod resetPeriod, Scope scope) {
token = id.toToken();
allocator = id.toAllocatorId().toRegisteredAllocator();
resetPeriod = id.toResetPeriod();
scope = id.toScope();
}
}
114 changes: 0 additions & 114 deletions src/lib/InternalLogic.sol
Original file line number Diff line number Diff line change
Expand Up @@ -84,21 +84,6 @@ contract InternalLogic is Tstorish {
_PERMIT2_INITIALLY_DEPLOYED = _checkPermit2Deployment();
}

function _emitClaim(address sponsor, bytes32 messageHash, address allocator) internal {
assembly ("memory-safe") {
mstore(0, messageHash)
log4(0, 0x20, _CLAIM_EVENT_SIGNATURE, shr(0x60, shl(0x60, sponsor)), shr(0x60, shl(0x60, allocator)), caller())
}
}

function _notExpiredAndSignedByAllocator(bytes32 messageHash, address allocator, BasicTransfer calldata transferPayload) internal {
transferPayload.expires.later();

messageHash.signedBy(allocator, transferPayload.allocatorSignature, _INITIAL_DOMAIN_SEPARATOR.toLatest(_INITIAL_CHAIN_ID));

_emitClaim(msg.sender, messageHash, allocator);
}

function _setReentrancyGuard() internal {
_setTstorish(_REENTRANCY_GUARD_SLOT, 1);
}
Expand All @@ -107,105 +92,6 @@ contract InternalLogic is Tstorish {
_clearTstorish(_REENTRANCY_GUARD_SLOT);
}

function _register(address sponsor, bytes32 claimHash, bytes32 typehash, uint256 duration) internal {
assembly ("memory-safe") {
let m := mload(0x40)
mstore(add(m, 0x14), sponsor)
mstore(m, _ACTIVE_REGISTRATIONS_SCOPE)
mstore(add(m, 0x34), claimHash)
mstore(add(m, 0x54), typehash)
let cutoffSlot := keccak256(add(m, 0x1c), 0x58)

let expires := add(timestamp(), duration)
if or(lt(expires, sload(cutoffSlot)), gt(duration, 0x278d00)) {
// revert InvalidRegistrationDuration(uint256 duration)
mstore(0, 0x1f9a96f4)
mstore(0x20, duration)
revert(0x1c, 0x24)
}

sstore(cutoffSlot, expires)
mstore(add(m, 0x74), expires)
log2(add(m, 0x34), 0x60, _COMPACT_REGISTERED_SIGNATURE, shr(0x60, shl(0x60, sponsor)))
}
}

function _registerWithDefaults(bytes32 claimHash, bytes32 typehash) internal {
_register(msg.sender, claimHash, typehash, uint256(0x258).asStubborn());
}

function _registerBatch(bytes32[2][] calldata claimHashesAndTypehashes, uint256 duration) internal returns (bool) {
unchecked {
uint256 totalClaimHashes = claimHashesAndTypehashes.length;
for (uint256 i = 0; i < totalClaimHashes; ++i) {
bytes32[2] calldata claimHashAndTypehash = claimHashesAndTypehashes[i];
_register(msg.sender, claimHashAndTypehash[0], claimHashAndTypehash[1], duration);
}
}

return true;
}

function _consume(uint256[] calldata nonces) internal returns (bool) {
// NOTE: this may not be necessary, consider removing
msg.sender.usingAllocatorId().mustHaveARegisteredAllocator();

unchecked {
uint256 i;

assembly ("memory-safe") {
i := nonces.offset
}

uint256 end = i + (nonces.length << 5);
uint256 nonce;
for (; i < end; i += 0x20) {
assembly ("memory-safe") {
nonce := calldataload(i)
}
nonce.consumeNonceAsAllocator(msg.sender);
}
}

return true;
}

function _registerAllocator(address allocator, bytes calldata proof) internal returns (uint96 allocatorId) {
allocator = uint256(uint160(allocator)).asSanitizedAddress();
if (!allocator.canBeRegistered(proof)) {
assembly ("memory-safe") {
// revert InvalidRegistrationProof(allocator)
mstore(0, 0x4e7f492b)
mstore(0x20, allocator)
revert(0x1c, 0x24)
}
}

allocatorId = allocator.register();
}

function _getLockDetails(uint256 id) internal view returns (address token, address allocator, ResetPeriod resetPeriod, Scope scope) {
token = id.toToken();
allocator = id.toAllocatorId().toRegisteredAllocator();
resetPeriod = id.toResetPeriod();
scope = id.toScope();
}

function _hasConsumedAllocatorNonce(uint256 nonce, address allocator) internal view returns (bool) {
return allocator.hasConsumedAllocatorNonce(nonce);
}

function _getRegistrationStatus(address sponsor, bytes32 claimHash, bytes32 typehash) internal view returns (uint256 expires) {
assembly ("memory-safe") {
let m := mload(0x40)
mstore(add(m, 0x14), sponsor)
mstore(m, _ACTIVE_REGISTRATIONS_SCOPE)
mstore(add(m, 0x34), claimHash)
mstore(add(m, 0x54), typehash)
expires := sload(keccak256(add(m, 0x1c), 0x58))
}
}

function _isPermit2Deployed() internal view returns (bool) {
if (_PERMIT2_INITIALLY_DEPLOYED) {
return true;
Expand Down
Loading

0 comments on commit 0fbcc2d

Please sign in to comment.