Created
March 22, 2023 05:55
-
-
Save KaiCode2/55f9ce7dbe6461e068f11e7f36d22211 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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