Skip to content

Instantly share code, notes, and snippets.

@KaiCode2
Created March 22, 2023 05:55
Show Gist options
  • Save KaiCode2/55f9ce7dbe6461e068f11e7f36d22211 to your computer and use it in GitHub Desktop.
Save KaiCode2/55f9ce7dbe6461e068f11e7f36d22211 to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.2 <0.9.0;
library PartiallyApplied {
struct PartiallyEncodedCall {
address callee;
bytes4 selector;
bytes partialPayload;
}
function callPartiallyApplied(PartiallyEncodedCall memory partiallyApplied, uint256 tokenId) public returns(bool) {
(bool success, bytes memory response) = partiallyApplied.callee.call(
abi.encodeWithSelector(
partiallyApplied.selector, abi.encode(tokenId, partiallyApplied.partialPayload)
)
);
require(success, "PartiallyApplied: Call failed");
return abi.decode(response, (bool));
}
}
contract Verifier {
using PartiallyApplied for PartiallyApplied.PartiallyEncodedCall;
mapping(bytes4 => PartiallyApplied.PartiallyEncodedCall) internal partials;
function makePartiallyApplied(
PartiallyApplied.PartiallyEncodedCall memory partiallyApplied
) public returns(function (uint256) external view returns(bool) verify) {
(bytes4 newSelector,) = abi.decode(
abi.encode(keccak256(abi.encode(partiallyApplied))),
(bytes4, bytes28)
);
partials[newSelector] = partiallyApplied;
address callee = partiallyApplied.callee;
assembly {
verify.address := callee
verify.selector := newSelector
}
}
function makeTechTypeConstraint(uint256 techType) public returns(function (uint256) external view returns(bool) verify) {
PartiallyApplied.PartiallyEncodedCall memory partiallyApplied = PartiallyApplied.PartiallyEncodedCall(
address(this), this.hasTechType.selector, abi.encode(techType)
);
return makePartiallyApplied(partiallyApplied);
}
function hasTechType(uint256 tokenId, uint256 techType) public view returns(bool) {
return techType == 1;
}
function exists(uint256 tokenId) public view returns(bool) {
return tokenId == 0;
}
fallback(bytes calldata input) external returns(bytes memory output) {
PartiallyApplied.PartiallyEncodedCall memory selected = partials[msg.sig];
if (selected.callee != address(0x0)) {
uint256 tokenId = abi.decode(input, (uint256));
bool success = selected.callPartiallyApplied(tokenId);
return abi.encode(success);
}
}
}
contract PolicyManager {
struct Policy {
function (uint256) external view returns(bool) verify;
}
TestVerifier internal verifier;
Policy[] internal policies;
constructor() {
verifier = new Verifier();
policies[0] = Policy(verifier.exists);
policies[1] = Policy(verifier.makeTechTypeConstraint(1));
}
function verify(uint256 index, uint256 tokenId) external view returns(bool) {
return policies[index].verify(tokenId);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment