Skip to content

Commit

Permalink
back under the limit (removed emissary logic)
Browse files Browse the repository at this point in the history
  • Loading branch information
0age committed Oct 25, 2024
1 parent 9a8e157 commit 65d5de5
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 90 deletions.
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ solc = '0.8.28'
evm_version='cancun'
via_ir = true
# optimizer_runs = 4_294_967_295
optimizer_runs = 200
optimizer_runs = 9
bytecode_hash = 'none'
src = "src"
out = "out"
Expand Down
80 changes: 6 additions & 74 deletions src/TheCompact.sol
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ import {
ExogenousQualifiedSplitBatchMultichainClaimWithWitness
} from "./types/BatchMultichainClaims.sol";

import { COMPACT_TYPEHASH, BATCH_COMPACT_TYPEHASH, MULTICHAIN_COMPACT_TYPEHASH, PERMIT2_DEPOSIT_WITNESS_FRAGMENT_HASH, EMISSARY_ASSIGNMENT_TYPEHASH } from "./types/EIP712Types.sol";
import { COMPACT_TYPEHASH, BATCH_COMPACT_TYPEHASH, MULTICHAIN_COMPACT_TYPEHASH, PERMIT2_DEPOSIT_WITNESS_FRAGMENT_HASH } from "./types/EIP712Types.sol";

import { SplitComponent, TransferComponent, SplitByIdComponent, BatchClaimComponent, SplitBatchClaimComponent } from "./types/Components.sol";

Expand All @@ -98,7 +98,7 @@ import { MetadataRenderer } from "./lib/MetadataRenderer.sol";
* formation (and, if necessary, involuntary dissolution) of "resource locks."
* This contract has not yet been properly tested, audited, or reviewed.
*/
contract TheCompact is ITheCompact, ERC6909, Extsload, Tstorish {
contract TheCompact is ITheCompact, ERC6909, Tstorish {
using HashLib for address;
using HashLib for bytes32;
using HashLib for uint256;
Expand Down Expand Up @@ -201,9 +201,6 @@ contract TheCompact is ITheCompact, ERC6909, Extsload, Tstorish {
// TODO: optimize
mapping(address => mapping(bytes32 => bytes32)) private _registeredClaimHashes;

// TODO: optimize
mapping(address => mapping(address => bool)) private _emissaries;

uint256 private immutable _INITIAL_CHAIN_ID;
bytes32 private immutable _INITIAL_DOMAIN_SEPARATOR;
MetadataRenderer private immutable _METADATA_RENDERER;
Expand Down Expand Up @@ -247,13 +244,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload, Tstorish {
}

function depositAndRegister(uint256[2][] calldata idsAndAmounts, bytes32[2][] calldata claimHashesAndTypehashes) external payable returns (bool) {
unchecked {
uint256 totalClaimHashes = claimHashesAndTypehashes.length;
for (uint256 i = 0; i < totalClaimHashes; ++i) {
bytes32[2] calldata claimHashAndTypehash = claimHashesAndTypehashes[i];
_registeredClaimHashes[msg.sender][claimHashAndTypehash[0]] = claimHashAndTypehash[1];
}
}
_registerFor(msg.sender, claimHashesAndTypehashes);

return _processBatchDeposit(idsAndAmounts, msg.sender);
}
Expand Down Expand Up @@ -891,68 +882,21 @@ contract TheCompact is ITheCompact, ERC6909, Extsload, Tstorish {
}

function register(bytes32[2][] calldata claimHashesAndTypehashes) external returns (bool) {
unchecked {
uint256 totalClaimHashes = claimHashesAndTypehashes.length;
for (uint256 i = 0; i < totalClaimHashes; ++i) {
bytes32[2] calldata claimHashAndTypehash = claimHashesAndTypehashes[i];
_registeredClaimHashes[msg.sender][claimHashAndTypehash[0]] = claimHashAndTypehash[1];
}
}

return true;
return _registerFor(msg.sender, claimHashesAndTypehashes);
}

function registerFor(address sponsor, bytes32 claimHash, bytes32 typehash) external returns (bool) {
// TODO: optimize
if (!_emissaries[sponsor][msg.sender]) {
revert InvalidEmissary(sponsor, msg.sender);
}
_registeredClaimHashes[sponsor][claimHash] = typehash;
return true;
}

function registerFor(address sponsor, bytes32[2][] calldata claimHashesAndTypehashes) external returns (bool) {
// TODO: optimize
if (!_emissaries[sponsor][msg.sender]) {
revert InvalidEmissary(sponsor, msg.sender);
}

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

return true;
}

function assignEmissary(address sponsor, address emissary, uint256 nonce, uint256 expires, bool assigned, bytes calldata sponsorSignature) external returns (bool) {
expires.later();

bytes32 messageHash;
assembly ("memory-safe") {
let m := mload(0x40) // Grab the free memory pointer; memory will be left dirtied.
mstore(m, EMISSARY_ASSIGNMENT_TYPEHASH)
mstore(add(m, 0x20), emissary)
mstore(add(m, 0x40), nonce)
mstore(add(m, 0x60), expires)
mstore(add(m, 0x80), assigned)
messageHash := keccak256(m, 0xa0)
}

messageHash.signedBy(sponsor, sponsorSignature, _INITIAL_DOMAIN_SEPARATOR.toLatest(_INITIAL_CHAIN_ID));

nonce.consumeNonceAsSponsor(sponsor);

return _assignEmissary(sponsor, emissary, assigned);
}

function assignEmissary(address emissary, bool assigned) external returns (bool) {
return _assignEmissary(msg.sender, emissary, assigned);
}

function consume(uint256[] calldata nonces) external returns (bool) {
// NOTE: this may not be necessary, consider removing
msg.sender.usingAllocatorId().mustHaveARegisteredAllocator();
Expand Down Expand Up @@ -1000,10 +944,6 @@ contract TheCompact is ITheCompact, ERC6909, Extsload, Tstorish {
consumed = allocator.hasConsumedAllocatorNonce(nonce);
}

function hasConsumedEmissaryAssignmentNonce(uint256 nonce, address sponsor) external view returns (bool consumed) {
consumed = sponsor.hasConsumedEmissaryAssignmentNonce(nonce);
}

function DOMAIN_SEPARATOR() external view returns (bytes32 domainSeparator) {
return _INITIAL_DOMAIN_SEPARATOR.toLatest(_INITIAL_CHAIN_ID);
}
Expand Down Expand Up @@ -1041,14 +981,6 @@ contract TheCompact is ITheCompact, ERC6909, Extsload, Tstorish {
_emitClaim(msg.sender, messageHash, allocator);
}

function _assignEmissary(address sponsor, address emissary, bool assigned) internal returns (bool) {
_emissaries[sponsor][emissary] = assigned;

emit EmissaryAssignment(sponsor, emissary, assigned);

return true;
}

function _processBasicTransfer(BasicTransfer calldata transfer, function(address, address, uint256, uint256) internal returns (bool) operation) internal returns (bool) {
_notExpiredAndSignedByAllocator(transfer.toMessageHash(), transfer.id.toRegisteredAllocatorWithConsumed(transfer.nonce), transfer);

Expand Down
12 changes: 0 additions & 12 deletions src/interfaces/ITheCompact.sol
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ interface ITheCompact {
event ForcedWithdrawalEnabled(address indexed account, uint256 indexed id, uint256 withdrawableAt);
event ForcedWithdrawalDisabled(address indexed account, uint256 indexed id);
event AllocatorRegistered(uint96 allocatorId, address allocator);
event EmissaryAssignment(address indexed sponsor, address indexed emissary, bool assigned);

error InvalidToken(address token);
error Expired(uint256 expiration);
Expand All @@ -97,7 +96,6 @@ interface ITheCompact {
error InvalidScope(uint256 id);
error InvalidDepositTokenOrdering();
error InvalidDepositBalanceChange();
error InvalidEmissary(address sponsor, address emissary);

function deposit(address allocator) external payable returns (uint256 id);

Expand Down Expand Up @@ -352,14 +350,6 @@ interface ITheCompact {

function register(bytes32[2][] calldata claimHashesAndTypehashes) external returns (bool);

function registerFor(address sponsor, bytes32 claimHash, bytes32 typehash) external returns (bool);

function registerFor(address sponsor, bytes32[2][] calldata claimHashesAndTypehashes) external returns (bool);

function assignEmissary(address sponsor, address emissary, uint256 nonce, uint256 expires, bool assigned, bytes calldata sponsorSignature) external returns (bool);

function assignEmissary(address emissary, bool assigned) external returns (bool);

function consume(uint256[] calldata nonces) external returns (bool);

function __registerAllocator(address allocator, bytes calldata proof) external returns (uint96 allocatorId);
Expand All @@ -370,8 +360,6 @@ interface ITheCompact {

function hasConsumedAllocatorNonce(uint256 nonce, address allocator) external view returns (bool consumed);

function hasConsumedEmissaryAssignmentNonce(uint256 nonce, address sponsor) external view returns (bool consumed);

function DOMAIN_SEPARATOR() external view returns (bytes32 domainSeparator);

/// @dev Returns the name for the contract.
Expand Down
96 changes: 96 additions & 0 deletions src/lib/EmissaryLib.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;

import { ConsumerLib } from "./ConsumerLib.sol";
import { ValidityLib } from "./ValidityLib.sol";
import { EMISSARY_ASSIGNMENT_TYPEHASH } from "../types/EIP712Types.sol";

// An emissary can register claims on behalf of a sponsor that has assigned them.
// It works kind of like setApprovalForAll and applies to all locks. One caveat
// is that allocators still have to authorize any claims, which reduces the risk
// of a fully rogue emissary depending on the allocator in question.
// NOTE: this idea is inherently risky; think about whether it's worth it!
abstract contract EmissaryLib {
using ValidityLib for uint256;
using ValidityLib for address;
using ConsumerLib for uint256;

event EmissaryAssignment(address indexed sponsor, address indexed emissary, bool assigned);

error InvalidEmissary(address sponsor, address emissary);

// TODO: optimize
mapping(address => mapping(address => bool)) private _emissaries;

// TODO: this mapping already exists on The Compact; just use one of them!
mapping(address => mapping(bytes32 => bytes32)) private _registeredClaimHashes;

function registerFor(address sponsor, bytes32 claimHash, bytes32 typehash) external returns (bool) {
// TODO: optimize
if (!_emissaries[sponsor][msg.sender]) {
revert InvalidEmissary(sponsor, msg.sender);
}
_registeredClaimHashes[sponsor][claimHash] = typehash;
return true;
}

function registerFor(address sponsor, bytes32[2][] calldata claimHashesAndTypehashes) external returns (bool) {
// TODO: optimize
if (!_emissaries[sponsor][msg.sender]) {
revert InvalidEmissary(sponsor, msg.sender);
}

return _registerFor(sponsor, claimHashesAndTypehashes);
}

function assignEmissary(address sponsor, address emissary, uint256 nonce, uint256 expires, bool assigned, bytes calldata sponsorSignature) external returns (bool) {
expires.later();

bytes32 messageHash;
assembly ("memory-safe") {
let m := mload(0x40) // Grab the free memory pointer; memory will be left dirtied.
mstore(m, EMISSARY_ASSIGNMENT_TYPEHASH)
mstore(add(m, 0x20), emissary)
mstore(add(m, 0x40), nonce)
mstore(add(m, 0x60), expires)
mstore(add(m, 0x80), assigned)
messageHash := keccak256(m, 0xa0)
}

// TODO: this function should be colocated with the rest of The Compact as it has the immutable args here
// messageHash.signedBy(sponsor, sponsorSignature, _INITIAL_DOMAIN_SEPARATOR.toLatest(_INITIAL_CHAIN_ID));

nonce.consumeNonceAsSponsor(sponsor);

return _assignEmissary(sponsor, emissary, assigned);
}

function assignEmissary(address emissary, bool assigned) external returns (bool) {
return _assignEmissary(msg.sender, emissary, assigned);
}

function hasConsumedEmissaryAssignmentNonce(uint256 nonce, address sponsor) external view returns (bool consumed) {
consumed = sponsor.hasConsumedEmissaryAssignmentNonce(nonce);
}

function _assignEmissary(address sponsor, address emissary, bool assigned) internal returns (bool) {
_emissaries[sponsor][emissary] = assigned;

emit EmissaryAssignment(sponsor, emissary, assigned);

return true;
}

// TODO: this is already on the compact, just use one of them
function _registerFor(address sponsor, bytes32[2][] calldata claimHashesAndTypehashes) internal returns (bool) {
unchecked {
uint256 totalClaimHashes = claimHashesAndTypehashes.length;
for (uint256 i = 0; i < totalClaimHashes; ++i) {
bytes32[2] calldata claimHashAndTypehash = claimHashesAndTypehashes[i];
_registeredClaimHashes[sponsor][claimHashAndTypehash[0]] = claimHashAndTypehash[1];
}
}

return true;
}
}
4 changes: 1 addition & 3 deletions src/lib/Extsload.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;

// TODO: add this back in once we have more headroom?
contract Extsload {
function extsload(bytes32 slot) external view returns (bytes32) {
assembly ("memory-safe") {
Expand All @@ -9,8 +10,6 @@ contract Extsload {
}
}

// TODO: add these back in once we have more headroom?
/*
function extsload(bytes32 startSlot, uint256 nSlots) external view returns (bytes32[] memory) {
assembly ("memory-safe") {
let memptr := mload(0x40)
Expand Down Expand Up @@ -56,5 +55,4 @@ contract Extsload {
return(start, sub(end, start))
}
}
*/
}

0 comments on commit 65d5de5

Please sign in to comment.