Address Contract Verified
Address
0x975df8A99C895d04ae158F8C91Ba562Fce3ECDA3
Balance
0 ETH
Nonce
12
Code Size
2895 bytes
Creator
Create2 Deployer at tx 0x7560e013...bf730d
Indexed Transactions
0
Contract Bytecode
2895 bytes
0x6080806040526004361015610012575f80fd5b5f905f3560e01c9081630a5623fb146105a05750806348c57f0f1461054f57806359659e901461052757806366f764741461047c57806374d5e100146103e057806383f94db7146102a3578063c4d66de8146101265763c6a188ca14610076575f80fd5b34610123578060031936011261012357600154604051635c60da1b60e01b815290602090829060049082906001600160a01b03165afa9081156101185782916100ce575b6040516001600160a01b0383168152602090f35b90506020813d602011610110575b816100e9602093836105c2565b8101031261010c57516001600160a01b038116810361010c57602091505f6100ba565b5080fd5b3d91506100dc565b6040513d84823e3d90fd5b80fd5b5034610123576020366003190112610123576004356001600160a01b0381169081900361010c575f516020610afa5f395f51905f5254604081901c60ff1615906001600160401b0381168015908161029b575b6001149081610291575b159081610288575b50610279576001600160401b031981166001175f516020610afa5f395f51905f525581610251575b505f516020610afa5f395f51905f52549160ff8360401c16156102425780156102335783546001600160a01b0319161783556101ed575080f35b60ff60401b19165f516020610afa5f395f51905f5255604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d290602090a180f35b63f68eb55360e01b8452600484fd5b631afcd79f60e31b8452600484fd5b6001600160481b0319166001600160401b01175f516020610afa5f395f51905f52555f6101b3565b63f92ee8a960e01b8452600484fd5b9050155f61018b565b303b159150610183565b839150610179565b50346103aa5760203660031901126103aa576004356001600160a01b03811691908290036103aa575f5460405163e58378bb60e01b81526001600160a01b0390911690602081600481855afa90811561039f575f916103ae575b50813b156103aa575f9060446040518094819363f26a83b360e01b835260048301523360248301525afa801561039f5761038c575b50600154909182916001600160a01b031690813b15610388578291602483926040519485938492631b2ce7f360e11b845260048401525af18015610118576103775750f35b81610381916105c2565b6101235780f35b5050fd5b61039891505f906105c2565b5f5f610332565b6040513d5f823e3d90fd5b5f80fd5b90506020813d6020116103d8575b816103c9602093836105c2565b810103126103aa57515f6102fd565b3d91506103bc565b346103aa5760203660031901126103aa576004356001600160a01b038116908190036103aa575f546040516274d5e160e81b81526004810192909252602090829060249082906001600160a01b03165afa801561039f575f90610449575b602090604051908152f35b506020813d602011610474575b81610463602093836105c2565b810103126103aa576020905161043e565b3d9150610456565b346103aa5760203660031901126103aa5760043580156105185761049e6105f9565b805115610509576020815191015ff53d151981151661039f576001600160a01b031680156104fa576020907f5b1fb064f052394d8a4407b16ef60a7cb24aa98b856f79f8385b902e027c89ce82604051838152a1604051908152f35b63b06ebf3d60e01b5f5260045ffd5b631328927760e21b5f5260045ffd5b6381e69d9b60e01b5f5260045ffd5b346103aa575f3660031901126103aa576001546040516001600160a01b039091168152602090f35b346103aa5760203660031901126103aa576020600b61056c6105f9565b828151910120604051906040820152600435838201523081520160ff8153605590206040516001600160a01b039091168152f35b346103aa575f3660031901126103aa575f546001600160a01b03168152602090f35b601f909101601f19168101906001600160401b038211908210176105e557604052565b634e487b7160e01b5f52604160045260245ffd5b61047a61067c60405161060f60208401826105c2565b82815260208101926106808439602060018060a01b03600154166040518281019182526040808201525f60608201526060815261064d6080826105c2565b6040519586945180918587015e840190838201905f8252519283915e01015f815203601f1981018352826105c2565b9056fe60a08060405261047a80380380916100178285610292565b833981016040828203126101eb5761002e826102c9565b602083015190926001600160401b0382116101eb57019080601f830112156101eb57815161005b816102dd565b926100696040519485610292565b8184526020840192602083830101116101eb57815f926020809301855e84010152823b15610274577fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5080546001600160a01b0319166001600160a01b038516908117909155604051635c60da1b60e01b8152909190602081600481865afa9081156101f7575f9161023a575b50803b1561021a5750817f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e5f80a282511561020257602060049260405193848092635c60da1b60e01b82525afa9182156101f7575f926101ae575b505f809161018a945190845af43d156101a6573d9161016e836102dd565b9261017c6040519485610292565b83523d5f602085013e6102f8565b505b608052604051610123908161035782396080518160180152f35b6060916102f8565b9291506020833d6020116101ef575b816101ca60209383610292565b810103126101eb575f80916101e161018a956102c9565b9394509150610150565b5f80fd5b3d91506101bd565b6040513d5f823e3d90fd5b505050341561018c5763b398979f60e01b5f5260045ffd5b634c9c8ce360e01b5f9081526001600160a01b0391909116600452602490fd5b90506020813d60201161026c575b8161025560209383610292565b810103126101eb57610266906102c9565b5f6100f5565b3d9150610248565b631933b43b60e21b5f9081526001600160a01b038416600452602490fd5b601f909101601f19168101906001600160401b038211908210176102b557604052565b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036101eb57565b6001600160401b0381116102b557601f01601f191660200190565b9061031c575080511561030d57805190602001fd5b63d6bda27560e01b5f5260045ffd5b8151158061034d575b61032d575090565b639996b31560e01b5f9081526001600160a01b0391909116600452602490fd5b50803b1561032556fe60806040819052635c60da1b60e01b81526020906004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa801560a2575f901560d1575060203d602011609c575b6080601f8201601f1916810191906001600160401b0383119083101760885760849160405260800160ad565b60d1565b634e487b7160e01b5f52604160045260245ffd5b503d6058565b6040513d5f823e3d90fd5b602090607f19011260cd576080516001600160a01b038116810360cd5790565b5f80fd5b5f8091368280378136915af43d5f803e1560e9573d5ff35b3d5ffdfea264697066735822122048e9a114e6ed6ff43c4eaf116a4e9f9fe8fcdfc403dcf37c865230ec65eb18b864736f6c634300081c0033f0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00a2646970667358221220e217cdde1a1362714c6fc9d64a8184ebe93f5e5d8cc9dd7dfa0bfa9d4fe396f464736f6c634300081c0033
Verified Source Code Full Match
Compiler: v0.8.28+commit.7893614a
EVM: cancun
Optimization: Yes (15 runs)
DealManagerFactory.sol 108 lines
/* .o.
.888.
.8"888.
.8' `888.
.88ooo8888.
.8' `888.
o88o o8888o
ooo ooooo . ooooo ooooooo ooooo
`88. .888' .o8 `888' `8888 d8'
888b d'888 .ooooo. .o888oo .oooo. 888 .ooooo. Y888..8P
8 Y88. .P 888 d88' `88b 888 `P )88b 888 d88' `88b `8888'
8 `888' 888 888ooo888 888 .oP"888 888 888ooo888 .8PY888.
8 Y 888 888 .o 888 . d8( 888 888 o 888 .o d8' `888b
o8o o888o `Y8bod8P' "888" `Y888""8o o888ooooood8 `Y8bod8P' o888o o88888o
.oooooo. .o8 .oooooo.
d8P' `Y8b "888 d8P' `Y8b
888 oooo ooo 888oooo. .ooooo. oooo d8b 888 .ooooo. oooo d8b oo.ooooo.
888 `88. .8' d88' `88b d88' `88b `888""8P 888 d88' `88b `888""8P 888' `88b
888 `88..8' 888 888 888ooo888 888 888 888 888 888 888 888
`88b ooo `888' 888 888 888 .o 888 `88b ooo 888 888 888 888 888 .o.
`Y8bood8P' .8' `Y8bod8P' `Y8bod8P' d888b `Y8bood8P' `Y8bod8P' d888b 888bod8P' Y8P
.o..P' 888
`Y8P' o888o
_______________________________________________________________________________________________________
All software, documentation and other files and information in this repository (collectively, the "Software")
are copyright MetaLeX Labs, Inc., a Delaware corporation.
All rights reserved.
The Software is proprietary and shall not, in part or in whole, be used, copied, modified, merged, published,
distributed, transmitted, sublicensed, sold, or otherwise used in any form or by any means, electronic or
mechanical, including photocopying, recording, or by any information storage and retrieval system,
except with the express prior written permission of the copyright holder.*/
pragma solidity 0.8.28;
import "@openzeppelin/contracts/utils/Create2.sol";
import "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";
import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";
import "./DealManager.sol";
import "./libs/auth.sol";
contract DealManagerFactory is BorgAuthACL {
error InvalidSalt();
error DeploymentFailed();
error ZeroAddress();
UpgradeableBeacon public beacon;
event DealManagerDeployed(address dealManager);
constructor(address _auth) {
// Deploy the implementation contract
beacon = new UpgradeableBeacon(address(new DealManager()), address(this));
initialize(_auth);
}
function initialize(address _auth) public initializer {
// Initialize BorgAuthACL
__BorgAuthACL_init(_auth);
}
function deployDealManager(bytes32 _salt) public returns (address) {
if (_salt == bytes32(0)) revert InvalidSalt();
// Create proxy deployment bytecode
bytes memory proxyBytecode = _getBytecode();
// Deploy using CREATE2
address dealManagerProxy = Create2.deploy(0, _salt, proxyBytecode);
if(dealManagerProxy == address(0)) revert DeploymentFailed();
emit DealManagerDeployed(dealManagerProxy);
return dealManagerProxy;
}
/// @notice Computes the deterministic address for a DealManagerBeaconProxy
/// @param _salt Salt used for CREATE2
/// @return computedAddress The precomputed address of the proxy
function computeDealManagerAddress(bytes32 _salt) external view returns (address) {
bytes memory proxyBytecode = _getBytecode();
return Create2.computeAddress(_salt, keccak256(proxyBytecode));
}
/// @notice Gets the bytecode for creating new DealManager proxies
/// @dev Internal function used by deployDealManager
/// @return bytecode The proxy contract creation bytecode
function _getBytecode() private view returns (bytes memory bytecode) {
bytes memory sourceCodeBytes = type(BeaconProxy).creationCode;
bytecode = abi.encodePacked(sourceCodeBytes, abi.encode(beacon, ""));
}
function upgradeImplementation(address _newImplementation) external onlyOwner {
UpgradeableBeacon(beacon).upgradeTo(_newImplementation);
}
function getBeaconImplementation() external view returns (address) {
return UpgradeableBeacon(beacon).implementation();
}
}
Create2.sol 92 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Create2.sol)
pragma solidity ^0.8.20;
import {Errors} from "./Errors.sol";
/**
* @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.
* `CREATE2` can be used to compute in advance the address where a smart
* contract will be deployed, which allows for interesting new mechanisms known
* as 'counterfactual interactions'.
*
* See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more
* information.
*/
library Create2 {
/**
* @dev There's no code to deploy.
*/
error Create2EmptyBytecode();
/**
* @dev Deploys a contract using `CREATE2`. The address where the contract
* will be deployed can be known in advance via {computeAddress}.
*
* The bytecode for a contract can be obtained from Solidity with
* `type(contractName).creationCode`.
*
* Requirements:
*
* - `bytecode` must not be empty.
* - `salt` must have not been used for `bytecode` already.
* - the factory must have a balance of at least `amount`.
* - if `amount` is non-zero, `bytecode` must have a `payable` constructor.
*/
function deploy(uint256 amount, bytes32 salt, bytes memory bytecode) internal returns (address addr) {
if (address(this).balance < amount) {
revert Errors.InsufficientBalance(address(this).balance, amount);
}
if (bytecode.length == 0) {
revert Create2EmptyBytecode();
}
assembly ("memory-safe") {
addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
// if no address was created, and returndata is not empty, bubble revert
if and(iszero(addr), not(iszero(returndatasize()))) {
let p := mload(0x40)
returndatacopy(p, 0, returndatasize())
revert(p, returndatasize())
}
}
if (addr == address(0)) {
revert Errors.FailedDeployment();
}
}
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the
* `bytecodeHash` or `salt` will result in a new destination address.
*/
function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {
return computeAddress(salt, bytecodeHash, address(this));
}
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at
* `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.
*/
function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address addr) {
assembly ("memory-safe") {
let ptr := mload(0x40) // Get free memory pointer
// | | ↓ ptr ... ↓ ptr + 0x0B (start) ... ↓ ptr + 0x20 ... ↓ ptr + 0x40 ... |
// |-------------------|---------------------------------------------------------------------------|
// | bytecodeHash | CCCCCCCCCCCCC...CC |
// | salt | BBBBBBBBBBBBB...BB |
// | deployer | 000000...0000AAAAAAAAAAAAAAAAAAA...AA |
// | 0xFF | FF |
// |-------------------|---------------------------------------------------------------------------|
// | memory | 000000...00FFAAAAAAAAAAAAAAAAAAA...AABBBBBBBBBBBBB...BBCCCCCCCCCCCCC...CC |
// | keccak(start, 85) | ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ |
mstore(add(ptr, 0x40), bytecodeHash)
mstore(add(ptr, 0x20), salt)
mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes
let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff
mstore8(start, 0xff)
addr := and(keccak256(start, 85), 0xffffffffffffffffffffffffffffffffffffffff)
}
}
}
BeaconProxy.sol 57 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.2.0) (proxy/beacon/BeaconProxy.sol)
pragma solidity ^0.8.22;
import {IBeacon} from "./IBeacon.sol";
import {Proxy} from "../Proxy.sol";
import {ERC1967Utils} from "../ERC1967/ERC1967Utils.sol";
/**
* @dev This contract implements a proxy that gets the implementation address for each call from an {UpgradeableBeacon}.
*
* The beacon address can only be set once during construction, and cannot be changed afterwards. It is stored in an
* immutable variable to avoid unnecessary storage reads, and also in the beacon storage slot specified by
* https://eips.ethereum.org/EIPS/eip-1967[ERC-1967] so that it can be accessed externally.
*
* CAUTION: Since the beacon address can never be changed, you must ensure that you either control the beacon, or trust
* the beacon to not upgrade the implementation maliciously.
*
* IMPORTANT: Do not use the implementation logic to modify the beacon storage slot. Doing so would leave the proxy in
* an inconsistent state where the beacon storage slot does not match the beacon address.
*/
contract BeaconProxy is Proxy {
// An immutable address for the beacon to avoid unnecessary SLOADs before each delegate call.
address private immutable _beacon;
/**
* @dev Initializes the proxy with `beacon`.
*
* If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This
* will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity
* constructor.
*
* Requirements:
*
* - `beacon` must be a contract with the interface {IBeacon}.
* - If `data` is empty, `msg.value` must be zero.
*/
constructor(address beacon, bytes memory data) payable {
ERC1967Utils.upgradeBeaconToAndCall(beacon, data);
_beacon = beacon;
}
/**
* @dev Returns the current implementation address of the associated beacon.
*/
function _implementation() internal view virtual override returns (address) {
return IBeacon(_getBeacon()).implementation();
}
/**
* @dev Returns the beacon.
*/
function _getBeacon() internal view virtual returns (address) {
return _beacon;
}
}
UpgradeableBeacon.sol 70 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/UpgradeableBeacon.sol)
pragma solidity ^0.8.20;
import {IBeacon} from "./IBeacon.sol";
import {Ownable} from "../../access/Ownable.sol";
/**
* @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their
* implementation contract, which is where they will delegate all function calls.
*
* An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.
*/
contract UpgradeableBeacon is IBeacon, Ownable {
address private _implementation;
/**
* @dev The `implementation` of the beacon is invalid.
*/
error BeaconInvalidImplementation(address implementation);
/**
* @dev Emitted when the implementation returned by the beacon is changed.
*/
event Upgraded(address indexed implementation);
/**
* @dev Sets the address of the initial implementation, and the initial owner who can upgrade the beacon.
*/
constructor(address implementation_, address initialOwner) Ownable(initialOwner) {
_setImplementation(implementation_);
}
/**
* @dev Returns the current implementation address.
*/
function implementation() public view virtual returns (address) {
return _implementation;
}
/**
* @dev Upgrades the beacon to a new implementation.
*
* Emits an {Upgraded} event.
*
* Requirements:
*
* - msg.sender must be the owner of the contract.
* - `newImplementation` must be a contract.
*/
function upgradeTo(address newImplementation) public virtual onlyOwner {
_setImplementation(newImplementation);
}
/**
* @dev Sets the implementation contract address for this beacon
*
* Requirements:
*
* - `newImplementation` must be a contract.
*/
function _setImplementation(address newImplementation) private {
if (newImplementation.code.length == 0) {
revert BeaconInvalidImplementation(newImplementation);
}
_implementation = newImplementation;
emit Upgraded(newImplementation);
}
}
DealManager.sol 464 lines
/* .o.
.888.
.8"888.
.8' `888.
.88ooo8888.
.8' `888.
o88o o8888o
ooo ooooo . ooooo ooooooo ooooo
`88. .888' .o8 `888' `8888 d8'
888b d'888 .ooooo. .o888oo .oooo. 888 .ooooo. Y888..8P
8 Y88. .P 888 d88' `88b 888 `P )88b 888 d88' `88b `8888'
8 `888' 888 888ooo888 888 .oP"888 888 888ooo888 .8PY888.
8 Y 888 888 .o 888 . d8( 888 888 o 888 .o d8' `888b
o8o o888o `Y8bod8P' "888" `Y888""8o o888ooooood8 `Y8bod8P' o888o o88888o
.oooooo. .o8 .oooooo.
d8P' `Y8b "888 d8P' `Y8b
888 oooo ooo 888oooo. .ooooo. oooo d8b 888 .ooooo. oooo d8b oo.ooooo.
888 `88. .8' d88' `88b d88' `88b `888""8P 888 d88' `88b `888""8P 888' `88b
888 `88..8' 888 888 888ooo888 888 888 888 888 888 888 888
`88b ooo `888' 888 888 888 .o 888 `88b ooo 888 888 888 888 888 .o.
`Y8bood8P' .8' `Y8bod8P' `Y8bod8P' d888b `Y8bood8P' `Y8bod8P' d888b 888bod8P' Y8P
.o..P' 888
`Y8P' o888o
_______________________________________________________________________________________________________
All software, documentation and other files and information in this repository (collectively, the "Software")
are copyright MetaLeX Labs, Inc., a Delaware corporation.
All rights reserved.
The Software is proprietary and shall not, in part or in whole, be used, copied, modified, merged, published,
distributed, transmitted, sublicensed, sold, or otherwise used in any form or by any means, electronic or
mechanical, including photocopying, recording, or by any information storage and retrieval system,
except with the express prior written permission of the copyright holder.*/
pragma solidity 0.8.28;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "./interfaces/IIssuanceManager.sol";
import "./libs/LexScroWLite.sol";
import "./libs/auth.sol";
import "./storage/DealManagerStorage.sol";
import "./storage/BorgAuthStorage.sol";
/// @title DealManager
/// @notice Manages the lifecycle of deals between parties, including creation, signing, payment, and finalization for a CyberCorp
/// @dev Implements UUPS upgradeable pattern and integrates with BorgAuth for access control
contract DealManager is Initializable, BorgAuthACL, LexScroWLite {
using DealManagerStorage for DealManagerStorage.DealManagerData;
error ZeroAddress();
error CounterPartyValueMismatch();
error AgreementConditionsNotMet();
error DealNotPending();
error PartyValuesLengthMismatch();
error ConditionAlreadyExists();
error ConditionDoesNotExist();
error NotUpgradeFactory();
error DealNotExpired();
/// @notice Emitted when a new deal is proposed
/// @param agreementId Unique identifier for the agreement
/// @param certAddress Address of the certificate contract
/// @param certId ID of the certificate
/// @param paymentToken Address of the token used for payment
/// @param paymentAmount Amount to be paid
/// @param templateId ID of the template used for the agreement
/// @param corp Address of the CyberCorp
/// @param dealRegistry Address of the CyberAgreementRegistry
/// @param parties Array of party addresses involved in the deal
/// @param conditions Array of condition contract addresses
/// @param hasSecret Whether the deal requires a secret for finalization
event DealProposed(
bytes32 indexed agreementId,
address[] certAddress,
uint256[] certId,
address paymentToken,
uint256 paymentAmount,
bytes32 templateId,
address corp,
address dealRegistry,
address[] parties,
address[] conditions,
bool hasSecret
);
event DealFinalized(
bytes32 indexed agreementId,
address indexed signer,
address indexed corp,
address dealRegistry,
bool fillUnallocated
);
/// @notice Maps agreement IDs to arrays of counter party values for closed deals.
mapping(bytes32 => string[]) public counterPartyValues;
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
/// @notice Initializes the DealManager contract
/// @dev Sets up the contract with required addresses and initializes parent contracts
/// @param _auth Address of the BorgAuth contract
/// @param _corp Address of the CyberCorp
/// @param _dealRegistry Address of the CyberAgreementRegistry
/// @param _issuanceManager Address of the CyberCorp's issuance manager
function initialize(address _auth, address _corp, address _dealRegistry, address _issuanceManager, address _upgradeFactory) public initializer {
__BorgAuthACL_init(_auth);
if (_corp == address(0)) revert ZeroAddress();
if (_dealRegistry == address(0)) revert ZeroAddress();
if (_issuanceManager == address(0)) revert ZeroAddress();
// Set storage values
LexScrowStorage.setCorp(_corp);
LexScrowStorage.setDealRegistry(_dealRegistry);
DealManagerStorage.setIssuanceManager(_issuanceManager);
// Initialize LexScroWLite without setting storage
__LexScroWLite_init(_corp, _dealRegistry);
DealManagerStorage.setUpgradeFactory(_upgradeFactory);
}
/// @notice Proposes a new deal
/// @dev Creates a new agreement and certificate for the deal
/// @param _certPrinterAddress Address of the certificate NFT contract
/// @param _paymentToken Address of the token used for payment
/// @param _paymentAmount Amount to be paid
/// @param _templateId ID of the agreement template to use
/// @param _salt Random value for unique agreement ID generation
/// @param _globalValues Array of global values for the agreement, must match the template
/// @param _parties Array of party addresses
/// @param _certDetails Details of the certificate to be created
/// @param _partyValues Array of party-specific values, must match the template
/// @param conditions Array of condition contract addresses
/// @param secretHash Hash of the secret required for finalization (if any)
/// @param expiry Timestamp when the deal expires
/// @return agreementId Unique identifier for the agreement
/// @return certIds IDs of the created certificate
function proposeDeal(
address[] memory _certPrinterAddress,
address _paymentToken,
uint256 _paymentAmount,
bytes32 _templateId,
uint256 _salt,
string[] memory _globalValues,
address[] memory _parties,
CertificateDetails[] memory _certDetails,
string[][] memory _partyValues,
address[] memory conditions,
bytes32 secretHash,
uint256 expiry
) public onlyOwner returns (bytes32 agreementId, uint256[] memory certIds) {
agreementId = ICyberAgreementRegistry(LexScrowStorage.getDealRegistry()).createContract(_templateId, _salt, _globalValues, _parties, _partyValues, secretHash, address(this), expiry);
Token[] memory corpAssets = new Token[](_certDetails.length);
certIds = new uint256[](_certDetails.length);
for(uint256 i = 0; i < _certDetails.length; i++) {
certIds[i] = DealManagerStorage.getIssuanceManager().createCert(_certPrinterAddress[i], address(this), _certDetails[i]);
corpAssets[i] = Token(TokenType.ERC721, _certPrinterAddress[i], certIds[i], 1);
}
Token[] memory buyerAssets = new Token[](1);
buyerAssets[0] = Token(TokenType.ERC20, _paymentToken, 0, _paymentAmount);
Escrow memory newEscrow = Escrow({
agreementId: agreementId,
counterParty: _parties[1],
corpAssets: corpAssets,
buyerAssets: buyerAssets,
signature: "",
expiry: expiry,
status: EscrowStatus.PENDING
});
LexScrowStorage.setEscrow(agreementId, newEscrow);
//set conditions
for(uint256 i = 0; i < conditions.length; i++) {
LexScrowStorage.addConditionToEscrow(agreementId, ICondition(conditions[i]));
}
emit DealProposed(
agreementId,
_certPrinterAddress,
certIds,
_paymentToken,
_paymentAmount,
_templateId,
LexScrowStorage.getCorp(),
LexScrowStorage.getDealRegistry(),
_parties,
conditions,
secretHash > 0
);
}
/// @notice Proposes and signs a deal in one transaction
/// @dev Combines deal proposal and initial signature
/// @param _certPrinterAddress Address of the certificate NFT contract
/// @param _paymentToken Address of the token used for payment
/// @param _paymentAmount Amount to be paid
/// @param _templateId ID of the agreement template to use
/// @param _salt Random value for unique agreement ID generation
/// @param _globalValues Array of global values for the agreement, must match the template
/// @param _parties Array of party addresses
/// @param _certDetails Details of the certificate to be created
/// @param proposer Address of the deal proposer
/// @param signature Signature of the proposer
/// @param _partyValues Array of party-specific values, must match the template
/// @param conditions Array of condition contract addresses
/// @param secretHash Hash of the secret required for finalization (if any)
/// @param expiry Timestamp when the deal expires
/// @return agreementId Unique identifier for the agreement
/// @return certIds IDs of the created certificate
function proposeAndSignDeal(
address[] memory _certPrinterAddress,
address _paymentToken,
uint256 _paymentAmount,
bytes32 _templateId,
uint256 _salt,
string[] memory _globalValues,
address[] memory _parties,
CertificateDetails[] memory _certDetails,
address proposer,
bytes memory signature,
string[][] memory _partyValues,
address[] memory conditions,
bytes32 secretHash,
uint256 expiry
) public returns (bytes32 agreementId, uint256[] memory certIds) {
if(_partyValues.length > _parties.length) revert PartyValuesLengthMismatch();
certIds = new uint256[](_certDetails.length);
(agreementId, certIds) = proposeDeal(_certPrinterAddress, _paymentToken, _paymentAmount, _templateId, _salt, _globalValues, _parties, _certDetails, _partyValues, conditions, secretHash, expiry);
// NOTE: proposer is expected to be listed as a party in the parties array.
// Update the escrow signature
Escrow storage escrow = LexScrowStorage.getEscrow(agreementId);
escrow.signature = signature;
if(_partyValues.length > 1) {
if(_partyValues[1].length != _partyValues[0].length) revert PartyValuesLengthMismatch();
DealManagerStorage.setCounterPartyValues(agreementId, _partyValues[1]);
}
ICyberAgreementRegistry(LexScrowStorage.getDealRegistry()).signContractFor(proposer, agreementId, _partyValues[0], signature, false, "");
}
/// @notice Signs a deal and processes payment
/// @dev Validates signature and processes payment for the deal
/// @param signer Address of the signer
/// @param agreementId Unique identifier for the agreement
/// @param signature Digital Signature hash of the signer
/// @param partyValues Array of party-specific values, must match the template
/// @param _fillUnallocated Whether to fill unallocated slots
/// @param name Name of the signer
/// @param secret Secret required for finalization (if any)
function signDealAndPay(
address signer,
bytes32 agreementId,
bytes memory signature,
string[] memory partyValues,
bool _fillUnallocated,
string memory name,
string memory secret
) public {
if(ICyberAgreementRegistry(LexScrowStorage.getDealRegistry()).isVoided(agreementId)) revert DealVoided();
if(ICyberAgreementRegistry(LexScrowStorage.getDealRegistry()).isFinalized(agreementId)) revert DealAlreadyFinalized();
Escrow storage escrow = LexScrowStorage.getEscrow(agreementId);
if(escrow.status != EscrowStatus.PENDING) revert DealNotPending();
if(escrow.expiry < block.timestamp) revert DealExpired();
string[] storage counterPartyCheck = DealManagerStorage.getCounterPartyValues(agreementId);
if(counterPartyCheck.length > 0) {
if (keccak256(abi.encode(counterPartyCheck)) != keccak256(abi.encode(partyValues))) revert CounterPartyValueMismatch();
}
else {
DealManagerStorage.setCounterPartyValues(agreementId, partyValues);
}
ICyberAgreementRegistry(LexScrowStorage.getDealRegistry()).signContractFor(signer, agreementId, partyValues, signature, _fillUnallocated, secret);
updateEscrow(agreementId, msg.sender, name);
handleCounterPartyPayment(agreementId);
}
/// @notice Signs and finalizes a deal in one transaction
/// @dev Combines signing, payment, and finalization steps
/// @param signer Address of the signer
/// @param agreementId Unique identifier for the agreement
/// @param partyValues Array of party-specific values, must match the template
/// @param signature Digital Signature hash of the signer
/// @param _fillUnallocated Whether to fill unallocated slots
/// @param name Name of the signer
/// @param secret Secret required for finalization (if any)
function signAndFinalizeDeal(
address signer,
bytes32 agreementId,
string[] memory partyValues,
bytes memory signature,
bool _fillUnallocated,
string memory name,
string memory secret
) public {
if(ICyberAgreementRegistry(LexScrowStorage.getDealRegistry()).isVoided(agreementId)) revert DealVoided();
if(ICyberAgreementRegistry(LexScrowStorage.getDealRegistry()).isFinalized(agreementId)) revert DealAlreadyFinalized();
if(LexScrowStorage.getEscrow(agreementId).status != EscrowStatus.PENDING) revert DealNotPending();
string[] storage counterPartyCheck = DealManagerStorage.getCounterPartyValues(agreementId);
if(counterPartyCheck.length > 0) {
if (keccak256(abi.encode(counterPartyCheck)) != keccak256(abi.encode(partyValues))) revert CounterPartyValueMismatch();
}
else {
DealManagerStorage.setCounterPartyValues(agreementId, partyValues);
}
if(!conditionCheck(agreementId)) revert AgreementConditionsNotMet();
if(!ICyberAgreementRegistry(LexScrowStorage.getDealRegistry()).hasSigned(agreementId, signer))
ICyberAgreementRegistry(LexScrowStorage.getDealRegistry()).signContractFor(signer, agreementId, partyValues, signature, _fillUnallocated, secret);
updateEscrow(agreementId, msg.sender, name);
handleCounterPartyPayment(agreementId);
finalizeDeal(agreementId);
}
/// @notice Finalizes a deal
/// @dev Checks signatures, conditions and finalizes the agreement
/// @param agreementId Unique identifier for the agreement
function finalizeDeal(bytes32 agreementId) public {
if(ICyberAgreementRegistry(LexScrowStorage.getDealRegistry()).isVoided(agreementId)) revert DealVoided();
if(LexScrowStorage.getEscrow(agreementId).status != EscrowStatus.PAID) revert DealNotPaid();
if(ICyberAgreementRegistry(LexScrowStorage.getDealRegistry()).isFinalized(agreementId)) revert DealAlreadyFinalized();
if(!ICyberAgreementRegistry(LexScrowStorage.getDealRegistry()).allPartiesSigned(agreementId)) revert DealNotFullySigned();
if(!conditionCheck(agreementId)) revert AgreementConditionsNotMet();
ICyberAgreementRegistry(LexScrowStorage.getDealRegistry()).finalizeContract(agreementId);
finalizeEscrow(agreementId);
emit DealFinalized(
agreementId,
msg.sender,
LexScrowStorage.getCorp(),
LexScrowStorage.getDealRegistry(),
false
);
}
/// @notice Voids an expired deal
/// @dev Voids the certificate and agreement for an expired deal
/// @param agreementId Unique identifier for the agreement
/// @param signer Address of the signer
/// @param signature Signature of the signer
function voidExpiredDeal(bytes32 agreementId, address signer, bytes memory signature) public {
Escrow storage deal = LexScrowStorage.getEscrow(agreementId);
if (block.timestamp <= deal.expiry) revert DealNotExpired();
ICyberAgreementRegistry(LexScrowStorage.getDealRegistry()).voidContractFor(agreementId, signer, signature);
for(uint256 i = 0; i < deal.corpAssets.length; i++) {
if(deal.corpAssets[i].tokenType == TokenType.ERC721) {
DealManagerStorage.getIssuanceManager().voidCertificate(
deal.corpAssets[i].tokenAddress,
deal.corpAssets[i].tokenId
);
}
}
if(deal.status == EscrowStatus.PAID)
voidAndRefund(agreementId);
else if(deal.status == EscrowStatus.PENDING)
voidEscrow(agreementId);
}
/// @notice Revokes a pending deal
/// @dev Can only be called for deals in pending status
/// @param agreementId Unique identifier for the agreement
/// @param signer Address of the signer
/// @param signature Signature of the signer
function revokeDeal(bytes32 agreementId, address signer, bytes memory signature) public {
if(LexScrowStorage.getEscrow(agreementId).status == EscrowStatus.PENDING)
ICyberAgreementRegistry(LexScrowStorage.getDealRegistry()).voidContractFor(agreementId, signer, signature);
else
revert DealNotPending();
}
/// @notice Signs to void a deal
/// @dev If the deal is paid, initiates refund process
/// @param agreementId Unique identifier for the agreement
/// @param signer Address of the signer
/// @param signature Signature of the signer
function signToVoid(bytes32 agreementId, address signer, bytes memory signature) public {
ICyberAgreementRegistry(LexScrowStorage.getDealRegistry()).voidContractFor(agreementId, signer, signature);
if(ICyberAgreementRegistry(LexScrowStorage.getDealRegistry()).isVoided(agreementId) && LexScrowStorage.getEscrow(agreementId).status == EscrowStatus.PAID)
voidAndRefund(agreementId);
}
/// @notice Adds a condition to a deal
/// @dev Can only be called by owner for pending deals
/// @param agreementId Unique identifier for the agreement
/// @param condition Address of the condition contract to add
function addCondition(bytes32 agreementId, address condition) public onlyOwner {
//make sure the contract is still pending
if(LexScrowStorage.getEscrow(agreementId).status != EscrowStatus.PENDING) revert DealNotPending();
//make sure the condition is not already in the list
ICondition[] storage conditions = LexScrowStorage.getConditionsByEscrow(agreementId);
for(uint256 i = 0; i < conditions.length; i++) {
if(conditions[i] == ICondition(condition)) revert ConditionAlreadyExists();
}
LexScrowStorage.addConditionToEscrow(agreementId, ICondition(condition));
}
/// @notice Removes a condition from a deal
/// @dev Can only be called by owner for pending deals
/// @param agreementId Unique identifier for the agreement
/// @param index Index of the condition to remove
function removeConditionAt(bytes32 agreementId, uint256 index) public onlyOwner {
//make sure the contract is still pending
if(LexScrowStorage.getEscrow(agreementId).status != EscrowStatus.PENDING) revert DealNotPending();
//make sure the condition is in the list
ICondition[] storage conditions = LexScrowStorage.getConditionsByEscrow(agreementId);
if(index >= conditions.length) revert ConditionDoesNotExist();
LexScrowStorage.removeConditionFromEscrow(agreementId, index);
}
/// @notice Sets the deal registry address
/// @dev Can only be called by owner
/// @param _dealRegistry New deal registry address
function setDealRegistry(address _dealRegistry) public onlyOwner {
LexScrowStorage.setDealRegistry(_dealRegistry);
}
/// @notice Sets the corporation address
/// @dev Can only be called by owner
/// @param _corp New corporation address
function setCorp(address _corp) public onlyOwner {
LexScrowStorage.setCorp(_corp);
}
/// @notice Sets the issuance manager address
/// @dev Can only be called by owner
/// @param _issuanceManager New issuance manager address
function setIssuanceManager(address _issuanceManager) public onlyOwner {
DealManagerStorage.setIssuanceManager(_issuanceManager);
}
/// @notice Gets the current issuance manager
/// @return IIssuanceManager The current issuance manager contract
function issuanceManager() public view returns (IIssuanceManager) {
return DealManagerStorage.getIssuanceManager();
}
/// @notice Gets the counter party values for an agreement
/// @param agreementId Unique identifier for the agreement
/// @return string[] Array of counter party values
function getCounterPartyValues(bytes32 agreementId) public view returns (string[] memory) {
return DealManagerStorage.getCounterPartyValues(agreementId);
}
}
auth.sol 214 lines
/* .o.
.888.
.8"888.
.8' `888.
.88ooo8888.
.8' `888.
o88o o8888o
ooo ooooo . ooooo ooooooo ooooo
`88. .888' .o8 `888' `8888 d8'
888b d'888 .ooooo. .o888oo .oooo. 888 .ooooo. Y888..8P
8 Y88. .P 888 d88' `88b 888 `P )88b 888 d88' `88b `8888'
8 `888' 888 888ooo888 888 .oP"888 888 888ooo888 .8PY888.
8 Y 888 888 .o 888 . d8( 888 888 o 888 .o d8' `888b
o8o o888o `Y8bod8P' "888" `Y888""8o o888ooooood8 `Y8bod8P' o888o o88888o
.oooooo. .o8 .oooooo.
d8P' `Y8b "888 d8P' `Y8b
888 oooo ooo 888oooo. .ooooo. oooo d8b 888 .ooooo. oooo d8b oo.ooooo.
888 `88. .8' d88' `88b d88' `88b `888""8P 888 d88' `88b `888""8P 888' `88b
888 `88..8' 888 888 888ooo888 888 888 888 888 888 888 888
`88b ooo `888' 888 888 888 .o 888 `88b ooo 888 888 888 888 888 .o.
`Y8bood8P' .8' `Y8bod8P' `Y8bod8P' d888b `Y8bood8P' `Y8bod8P' d888b 888bod8P' Y8P
.o..P' 888
`Y8P' o888o
_______________________________________________________________________________________________________
All software, documentation and other files and information in this repository (collectively, the "Software")
are copyright MetaLeX Labs, Inc., a Delaware corporation.
All rights reserved.
The Software is proprietary and shall not, in part or in whole, be used, copied, modified, merged, published,
distributed, transmitted, sublicensed, sold, or otherwise used in any form or by any means, electronic or
mechanical, including photocopying, recording, or by any information storage and retrieval system,
except with the express prior written permission of the copyright holder.*/
pragma solidity 0.8.28;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "../interfaces/IAuthAdapter.sol";
/// @title BorgAuth
/// @author MetaLeX Labs, Inc.
/// @notice ACL with extensibility for different role hierarchies and custom adapters
contract BorgAuth is Initializable {
//constants built-in roles, authority works as a hierarchy
uint256 public constant OWNER_ROLE = 99;
uint256 public constant ADMIN_ROLE = 98;
uint256 public constant PRIVILEGED_ROLE = 97;
address public pendingOwner;
//mappings and events
mapping(address => uint256) public userRoles;
mapping(uint256 => address) public roleAdapters;
event RoleUpdated(address indexed user, uint256 role);
event AdapterUpdated(uint256 indexed role, address adapter);
/// @dev user not authorized with given role
error BorgAuth_NotAuthorized(uint256 role, address user);
error BorgAuth_SetAnotherOwner();
error BorgAuth_ZeroAddress();
/// @notice Empty constructor for implementation contract
constructor(address owner) {
initialize(owner);
}
/// @notice Initializer replacing the constructor - sets the deployer/initializer as owner
/// @dev Use this instead of constructor when deployed behind a proxy
function initialize(address _owner) public initializer {
_updateRole(_owner, OWNER_ROLE);
}
/// @notice update role for user
/// @param user address of user
/// @param role role to update
function updateRole(
address user,
uint256 role
) external {
onlyRole(OWNER_ROLE, msg.sender);
_updateRole(user, role);
}
/// @notice initialize ownership transfer
/// @param newOwner address of new owner
function initTransferOwnership(address newOwner) external {
if (newOwner == address(0) || newOwner == msg.sender) revert BorgAuth_ZeroAddress();
onlyRole(OWNER_ROLE, msg.sender);
pendingOwner = newOwner;
}
/// @notice accept ownership transfer
function acceptOwnership() external {
if (msg.sender != pendingOwner) revert BorgAuth_NotAuthorized(OWNER_ROLE, msg.sender);
_updateRole(pendingOwner, OWNER_ROLE);
pendingOwner = address(0);
emit RoleUpdated(pendingOwner, OWNER_ROLE);
}
/// @notice function to purposefully revoke all roles from owner, rendering subsequent role updates impossible
/// @dev this function is intended for use to remove admin controls from subsequent contracts using this auth
function zeroOwner() external {
onlyRole(OWNER_ROLE, msg.sender);
_updateRole(msg.sender, 0);
}
/// @notice set adapter for role
/// @param _role role to set adapter for
/// @param _adapter address of adapter
function setRoleAdapter(uint256 _role, address _adapter) external {
onlyRole(OWNER_ROLE, msg.sender);
roleAdapters[_role] = _adapter;
emit AdapterUpdated(_role, _adapter);
}
/// @notice check role for user, revert if not authorized
/// @param user address of user
/// @param role of user
function onlyRole(uint256 role, address user) public view {
uint256 authorized = userRoles[user];
if (authorized < role) {
address adapter = roleAdapters[role];
if (adapter != address(0))
if (IAuthAdapter(adapter).isAuthorized(user) >= role)
return;
revert BorgAuth_NotAuthorized(role, user);
}
}
/// @notice check role for user, revert if not authorized
/// @param user address of user
/// @param role of user
function matchRole(uint256 role, address user) public view {
uint256 authorized = userRoles[user];
if (authorized != role) {
address adapter = roleAdapters[role];
if (adapter != address(0))
if (IAuthAdapter(adapter).isAuthorized(user) == role)
return;
revert BorgAuth_NotAuthorized(role, user);
}
}
/// @notice internal function to add a role to a user
/// @param role role to update
/// @param user address of user
function _updateRole(
address user,
uint256 role
) internal {
userRoles[user] = role;
emit RoleUpdated(user, role);
}
}
/// @title BorgAuthACL
/// @notice ACL with modifiers for different roles
abstract contract BorgAuthACL is Initializable {
//BorgAuth instance
BorgAuth public AUTH;
// @dev zero address error
error BorgAuthACL_ZeroAddress();
/// @notice Empty constructor for implementation contract
constructor() {
}
/// @notice Initializer for BorgAuthACL
/// @param _auth Address of the BorgAuth contract
function __BorgAuthACL_init(address _auth) internal onlyInitializing {
if(_auth == address(0)) revert BorgAuthACL_ZeroAddress();
AUTH = BorgAuth(_auth);
}
function userRoles(address user) public view returns (uint256) {
return AUTH.userRoles(user);
}
//common modifiers and general access control onlyRole
modifier onlyOwner() {
AUTH.onlyRole(AUTH.OWNER_ROLE(), msg.sender);
_;
}
modifier onlyAdmin() {
AUTH.onlyRole(AUTH.ADMIN_ROLE(), msg.sender);
_;
}
modifier onlyPriv() {
AUTH.onlyRole(AUTH.PRIVILEGED_ROLE(), msg.sender);
_;
}
modifier onlyRole(uint256 _role) {
AUTH.onlyRole(_role, msg.sender);
_;
}
modifier matchRole(uint256 _role) {
AUTH.matchRole(_role, msg.sender);
_;
}
}
Errors.sol 34 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of common custom errors used in multiple contracts
*
* IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.
* It is recommended to avoid relying on the error API for critical functionality.
*
* _Available since v5.1._
*/
library Errors {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error InsufficientBalance(uint256 balance, uint256 needed);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedCall();
/**
* @dev The deployment failed.
*/
error FailedDeployment();
/**
* @dev A necessary precompile is missing.
*/
error MissingPrecompile(address);
}
IBeacon.sol 16 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)
pragma solidity ^0.8.20;
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeacon {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {UpgradeableBeacon} will check that this address is a contract.
*/
function implementation() external view returns (address);
}
Proxy.sol 69 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/Proxy.sol)
pragma solidity ^0.8.20;
/**
* @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
* instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
* be specified by overriding the virtual {_implementation} function.
*
* Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
* different contract through the {_delegate} function.
*
* The success and return data of the delegated call will be returned back to the caller of the proxy.
*/
abstract contract Proxy {
/**
* @dev Delegates the current call to `implementation`.
*
* This function does not return to its internal call site, it will return directly to the external caller.
*/
function _delegate(address implementation) internal virtual {
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize())
// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
// Copy the returned data.
returndatacopy(0, 0, returndatasize())
switch result
// delegatecall returns 0 on error.
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
/**
* @dev This is a virtual function that should be overridden so it returns the address to which the fallback
* function and {_fallback} should delegate.
*/
function _implementation() internal view virtual returns (address);
/**
* @dev Delegates the current call to the address returned by `_implementation()`.
*
* This function does not return to its internal call site, it will return directly to the external caller.
*/
function _fallback() internal virtual {
_delegate(_implementation());
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
* function in the contract matches the call data.
*/
fallback() external payable virtual {
_fallback();
}
}
ERC1967Utils.sol 177 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.2.0) (proxy/ERC1967/ERC1967Utils.sol)
pragma solidity ^0.8.22;
import {IBeacon} from "../beacon/IBeacon.sol";
import {IERC1967} from "../../interfaces/IERC1967.sol";
import {Address} from "../../utils/Address.sol";
import {StorageSlot} from "../../utils/StorageSlot.sol";
/**
* @dev This library provides getters and event emitting update functions for
* https://eips.ethereum.org/EIPS/eip-1967[ERC-1967] slots.
*/
library ERC1967Utils {
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1.
*/
// solhint-disable-next-line private-vars-leading-underscore
bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev The `implementation` of the proxy is invalid.
*/
error ERC1967InvalidImplementation(address implementation);
/**
* @dev The `admin` of the proxy is invalid.
*/
error ERC1967InvalidAdmin(address admin);
/**
* @dev The `beacon` of the proxy is invalid.
*/
error ERC1967InvalidBeacon(address beacon);
/**
* @dev An upgrade function sees `msg.value > 0` that may be lost.
*/
error ERC1967NonPayable();
/**
* @dev Returns the current implementation address.
*/
function getImplementation() internal view returns (address) {
return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;
}
/**
* @dev Stores a new address in the ERC-1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
if (newImplementation.code.length == 0) {
revert ERC1967InvalidImplementation(newImplementation);
}
StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;
}
/**
* @dev Performs implementation upgrade with additional setup call if data is nonempty.
* This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
* to avoid stuck value in the contract.
*
* Emits an {IERC1967-Upgraded} event.
*/
function upgradeToAndCall(address newImplementation, bytes memory data) internal {
_setImplementation(newImplementation);
emit IERC1967.Upgraded(newImplementation);
if (data.length > 0) {
Address.functionDelegateCall(newImplementation, data);
} else {
_checkNonPayable();
}
}
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1.
*/
// solhint-disable-next-line private-vars-leading-underscore
bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Returns the current admin.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using
* the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
*/
function getAdmin() internal view returns (address) {
return StorageSlot.getAddressSlot(ADMIN_SLOT).value;
}
/**
* @dev Stores a new address in the ERC-1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
if (newAdmin == address(0)) {
revert ERC1967InvalidAdmin(address(0));
}
StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {IERC1967-AdminChanged} event.
*/
function changeAdmin(address newAdmin) internal {
emit IERC1967.AdminChanged(getAdmin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
* This is the keccak-256 hash of "eip1967.proxy.beacon" subtracted by 1.
*/
// solhint-disable-next-line private-vars-leading-underscore
bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
/**
* @dev Returns the current beacon.
*/
function getBeacon() internal view returns (address) {
return StorageSlot.getAddressSlot(BEACON_SLOT).value;
}
/**
* @dev Stores a new beacon in the ERC-1967 beacon slot.
*/
function _setBeacon(address newBeacon) private {
if (newBeacon.code.length == 0) {
revert ERC1967InvalidBeacon(newBeacon);
}
StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;
address beaconImplementation = IBeacon(newBeacon).implementation();
if (beaconImplementation.code.length == 0) {
revert ERC1967InvalidImplementation(beaconImplementation);
}
}
/**
* @dev Change the beacon and trigger a setup call if data is nonempty.
* This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
* to avoid stuck value in the contract.
*
* Emits an {IERC1967-BeaconUpgraded} event.
*
* CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since
* it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for
* efficiency.
*/
function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {
_setBeacon(newBeacon);
emit IERC1967.BeaconUpgraded(newBeacon);
if (data.length > 0) {
Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
} else {
_checkNonPayable();
}
}
/**
* @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract
* if an upgrade doesn't perform an initialization call.
*/
function _checkNonPayable() private {
if (msg.value > 0) {
revert ERC1967NonPayable();
}
}
}
Ownable.sol 100 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
Initializable.sol 238 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.20;
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Storage of the initializable contract.
*
* It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
* when using with upgradeable contracts.
*
* @custom:storage-location erc7201:openzeppelin.storage.Initializable
*/
struct InitializableStorage {
/**
* @dev Indicates that the contract has been initialized.
*/
uint64 _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool _initializing;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
/**
* @dev The contract is already initialized.
*/
error InvalidInitialization();
/**
* @dev The contract is not initializing.
*/
error NotInitializing();
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint64 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
* number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
* production.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
// Cache values to avoid duplicated sloads
bool isTopLevelCall = !$._initializing;
uint64 initialized = $._initialized;
// Allowed calls:
// - initialSetup: the contract is not in the initializing state and no previous version was
// initialized
// - construction: the contract is initialized at version 1 (no reinitialization) and the
// current contract is just being deployed
bool initialSetup = initialized == 0 && isTopLevelCall;
bool construction = initialized == 1 && address(this).code.length == 0;
if (!initialSetup && !construction) {
revert InvalidInitialization();
}
$._initialized = 1;
if (isTopLevelCall) {
$._initializing = true;
}
_;
if (isTopLevelCall) {
$._initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint64 version) {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing || $._initialized >= version) {
revert InvalidInitialization();
}
$._initialized = version;
$._initializing = true;
_;
$._initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
_checkInitializing();
_;
}
/**
* @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
*/
function _checkInitializing() internal view virtual {
if (!_isInitializing()) {
revert NotInitializing();
}
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing) {
revert InvalidInitialization();
}
if ($._initialized != type(uint64).max) {
$._initialized = type(uint64).max;
emit Initialized(type(uint64).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint64) {
return _getInitializableStorage()._initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _getInitializableStorage()._initializing;
}
/**
* @dev Pointer to storage slot. Allows integrators to override it with a custom storage location.
*
* NOTE: Consider following the ERC-7201 formula to derive storage locations.
*/
function _initializableStorageSlot() internal pure virtual returns (bytes32) {
return INITIALIZABLE_STORAGE;
}
/**
* @dev Returns a pointer to the storage namespace.
*/
// solhint-disable-next-line var-name-mixedcase
function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
bytes32 slot = _initializableStorageSlot();
assembly {
$.slot := slot
}
}
}
IIssuanceManager.sol 177 lines
/* .o.
.888.
.8"888.
.8' `888.
.88ooo8888.
.8' `888.
o88o o8888o
ooo ooooo . ooooo ooooooo ooooo
`88. .888' .o8 `888' `8888 d8'
888b d'888 .ooooo. .o888oo .oooo. 888 .ooooo. Y888..8P
8 Y88. .P 888 d88' `88b 888 `P )88b 888 d88' `88b `8888'
8 `888' 888 888ooo888 888 .oP"888 888 888ooo888 .8PY888.
8 Y 888 888 .o 888 . d8( 888 888 o 888 .o d8' `888b
o8o o888o `Y8bod8P' "888" `Y888""8o o888ooooood8 `Y8bod8P' o888o o88888o
.oooooo. .o8 .oooooo.
d8P' `Y8b "888 d8P' `Y8b
888 oooo ooo 888oooo. .ooooo. oooo d8b 888 .ooooo. oooo d8b oo.ooooo.
888 `88. .8' d88' `88b d88' `88b `888""8P 888 d88' `88b `888""8P 888' `88b
888 `88..8' 888 888 888ooo888 888 888 888 888 888 888 888
`88b ooo `888' 888 888 888 .o 888 `88b ooo 888 888 888 888 888 .o.
`Y8bood8P' .8' `Y8bod8P' `Y8bod8P' d888b `Y8bood8P' `Y8bod8P' d888b 888bod8P' Y8P
.o..P' 888
`Y8P' o888o
_______________________________________________________________________________________________________
All software, documentation and other files and information in this repository (collectively, the "Software")
are copyright MetaLeX Labs, Inc., a Delaware corporation.
All rights reserved.
The Software is proprietary and shall not, in part or in whole, be used, copied, modified, merged, published,
distributed, transmitted, sublicensed, sold, or otherwise used in any form or by any means, electronic or
mechanical, including photocopying, recording, or by any information storage and retrieval system,
except with the express prior written permission of the copyright holder.*/
pragma solidity 0.8.28;
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
import "./ICyberCorp.sol";
import "./ITransferRestrictionHook.sol";
import "../CyberCorpConstants.sol";
import "../storage/CyberCertPrinterStorage.sol";
//Adapter interface for custom auth roles. Allows extensibility for different auth protocols i.e. hats.
interface IIssuanceManager is IERC721, IERC721Enumerable, IERC721Metadata {
// Events
event CertificateCreated(uint256 indexed tokenId, address indexed investor, uint256 amount, uint256 cap);
event Converted(uint256 indexed oldTokenId, uint256 indexed newTokenId);
event CertificateSigned(uint256 indexed tokenId, string signatureURI);
event CertificateEndorsed(uint256 indexed tokenId, address indexed endorser, string signatureURI);
event HookStatusChanged(bool enabled);
event WhitelistUpdated(address indexed account, bool whitelisted);
// Issuance Manager Functions
function initialize(
address _auth,
address _CORP,
address _CyberCertPrinterImplementation,
address _uriBuilder,
address _upgradeFactory
) external;
function createCertPrinter(
string[] memory _ledger,
string memory _name,
string memory _ticker,
string memory _certificateUri,
SecurityClass _securityClass,
SecuritySeries _securitySeries,
address _extension
) external returns (address);
function createCert(
address certAddress,
address to,
CertificateDetails memory _details
) external returns (uint256);
function assignCert(
address certAddress,
address from,
uint256 tokenId,
address investor,
CertificateDetails memory _details
) external;
function createCertAndAssign(
address certAddress,
address investor,
CertificateDetails memory _details
) external returns (uint256 tokenId);
function signCertificate(
address certAddress,
uint256 tokenId,
string calldata signatureURI
) external;
function endorseCertificate(
address certAddress,
uint256 tokenId,
address endorser,
string calldata signatureURI
) external;
function updateCertificateDetails(
address certAddress,
uint256 tokenId,
CertificateDetails memory _details
) external;
function voidCertificate(
address certAddress,
uint256 tokenId
) external;
function convert(
address certAddress,
uint256 tokenId,
address convertTo,
uint256 stockAmount
) external;
function upgradeImplementation(
address _newImplementation
) external;
function getBeaconImplementation() external view returns (address);
// Certificate Details Functions
function getCertificateDetails(
uint256 tokenId
) external view returns (CertificateDetails memory);
function getEndorsementHistory(
uint256 tokenId,
uint256 index
) external view returns (
address endorser,
string memory signatureURI,
uint256 timestamp
);
// Transfer Hook Functions
function setRestrictionHook(
uint256 _id,
address _hookAddress
) external;
function setGlobalRestrictionHook(
address hookAddress
) external;
function restrictionHooksById(
uint256 tokenId
) external view returns (ITransferRestrictionHook);
function globalRestrictionHook() external view returns (ITransferRestrictionHook);
// Beacon Functions
function CyberCertPrinterBeacon() external view returns (address);
function CORP() external view returns (address);
function uriBuilder() external view returns (address);
function certifications(uint256) external view returns (address);
function companyName() external view returns (string memory);
function companyJurisdiction() external view returns (string memory);
function AUTH() external view returns (address);
}
LexScroWLite.sol 227 lines
/* .o.
.888.
.8"888.
.8' `888.
.88ooo8888.
.8' `888.
o88o o8888o
ooo ooooo . ooooo ooooooo ooooo
`88. .888' .o8 `888' `8888 d8'
888b d'888 .ooooo. .o888oo .oooo. 888 .ooooo. Y888..8P
8 Y88. .P 888 d88' `88b 888 `P )88b 888 d88' `88b `8888'
8 `888' 888 888ooo888 888 .oP"888 888 888ooo888 .8PY888.
8 Y 888 888 .o 888 . d8( 888 888 o 888 .o d8' `888b
o8o o888o `Y8bod8P' "888" `Y888""8o o888ooooood8 `Y8bod8P' o888o o88888o
.oooooo. .o8 .oooooo.
d8P' `Y8b "888 d8P' `Y8b
888 oooo ooo 888oooo. .ooooo. oooo d8b 888 .ooooo. oooo d8b oo.ooooo.
888 `88. .8' d88' `88b d88' `88b `888""8P 888 d88' `88b `888""8P 888' `88b
888 `88..8' 888 888 888ooo888 888 888 888 888 888 888 888
`88b ooo `888' 888 888 888 .o 888 `88b ooo 888 888 888 888 888 .o.
`Y8bood8P' .8' `Y8bod8P' `Y8bod8P' d888b `Y8bood8P' `Y8bod8P' d888b 888bod8P' Y8P
.o..P' 888
`Y8P' o888o
_______________________________________________________________________________________________________
All software, documentation and other files and information in this repository (collectively, the "Software")
are copyright MetaLeX Labs, Inc., a Delaware corporation.
All rights reserved.
The Software is proprietary and shall not, in part or in whole, be used, copied, modified, merged, published,
distributed, transmitted, sublicensed, sold, or otherwise used in any form or by any means, electronic or
mechanical, including photocopying, recording, or by any information storage and retrieval system,
except with the express prior written permission of the copyright holder.*/
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "../interfaces/ICyberCorp.sol";
import "../interfaces/ICyberAgreementRegistry.sol";
import "../interfaces/ICyberCertPrinter.sol";
import "../interfaces/ICondition.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {LexScrowStorage, Escrow, Token, TokenType, EscrowStatus} from "../storage/LexScrowStorage.sol";
abstract contract LexScroWLite is Initializable, ReentrancyGuard {
using LexScrowStorage for LexScrowStorage.LexScrowData;
error DealExpired();
error EscrowNotPending();
error EscrowNotPaid();
error CounterPartyNotSet();
error DealNotFullySigned();
error DealNotFinalized();
error DealAlreadyFinalized();
error DealNotVoided();
error DealNotPaid();
error DealVoided();
event DealVoidedAt(bytes32 indexed agreementId, address agreementRegistry, uint256 timestamp);
event DealPaidAt(bytes32 indexed agreementId, address agreementRegistry, uint256 timestamp);
event DealFinalizedAt(bytes32 indexed agreementId, address agreementRegistry, uint256 timestamp);
constructor() {
}
function __LexScroWLite_init(address _corp, address _dealRegistry) internal onlyInitializing {
LexScrowStorage.setCorp(_corp);
LexScrowStorage.setDealRegistry(_dealRegistry);
}
function createEscrow(bytes32 agreementId, address counterParty, Token[] memory corpAssets, Token[] memory buyerAssets, uint256 expiry) internal {
bytes memory blankSignature = abi.encodePacked(bytes32(0));
Escrow memory newEscrow = Escrow({
agreementId: agreementId,
counterParty: counterParty,
corpAssets: corpAssets,
buyerAssets: buyerAssets,
signature: blankSignature,
expiry: expiry,
status: EscrowStatus.PENDING
});
LexScrowStorage.setEscrow(agreementId, newEscrow);
}
function updateEscrow(bytes32 agreementId, address counterParty, string memory buyerName) internal {
Escrow storage escrow = LexScrowStorage.getEscrow(agreementId);
escrow.counterParty = counterParty;
Endorsement memory newEndorsement = Endorsement(
address(this),
block.timestamp,
escrow.signature,
LexScrowStorage.getDealRegistry(),
agreementId,
escrow.counterParty,
buyerName
);
for(uint256 i = 0; i < escrow.corpAssets.length; i++) {
if(escrow.corpAssets[i].tokenType == TokenType.ERC721) {
ICyberCertPrinter(escrow.corpAssets[i].tokenAddress).addEndorsement(escrow.corpAssets[i].tokenId, newEndorsement);
}
}
}
function handleCounterPartyPayment(bytes32 agreementId) internal {
Escrow storage escrow = LexScrowStorage.getEscrow(agreementId);
if(escrow.status != EscrowStatus.PENDING) revert EscrowNotPending();
if(escrow.counterParty == address(0)) revert CounterPartyNotSet();
for(uint256 i = 0; i < escrow.buyerAssets.length; i++) {
if(escrow.buyerAssets[i].tokenType == TokenType.ERC20) {
IERC20(escrow.buyerAssets[i].tokenAddress).transferFrom(escrow.counterParty, address(this), escrow.buyerAssets[i].amount);
}
else if(escrow.buyerAssets[i].tokenType == TokenType.ERC721) {
IERC721(escrow.buyerAssets[i].tokenAddress).safeTransferFrom(escrow.counterParty, address(this), escrow.buyerAssets[i].tokenId);
}
else if(escrow.buyerAssets[i].tokenType == TokenType.ERC1155) {
IERC1155(escrow.buyerAssets[i].tokenAddress).safeTransferFrom(escrow.counterParty, address(this), escrow.buyerAssets[i].tokenId, escrow.buyerAssets[i].amount, "");
}
}
emit DealPaidAt(agreementId, LexScrowStorage.getDealRegistry(), block.timestamp);
escrow.status = EscrowStatus.PAID;
}
function voidAndRefund(bytes32 agreementId) internal nonReentrant {
Escrow storage escrow = LexScrowStorage.getEscrow(agreementId);
if(escrow.status != EscrowStatus.PAID) revert EscrowNotPaid();
if(!ICyberAgreementRegistry(LexScrowStorage.getDealRegistry()).isVoided(agreementId)) revert DealNotVoided();
// Refund buyer assets first
for(uint256 i = 0; i < escrow.buyerAssets.length; i++) {
if(escrow.buyerAssets[i].tokenType == TokenType.ERC20) {
IERC20(escrow.buyerAssets[i].tokenAddress).transfer(escrow.counterParty, escrow.buyerAssets[i].amount);
}
else if(escrow.buyerAssets[i].tokenType == TokenType.ERC721) {
IERC721(escrow.buyerAssets[i].tokenAddress).safeTransferFrom(address(this), escrow.counterParty, escrow.buyerAssets[i].tokenId);
}
else if(escrow.buyerAssets[i].tokenType == TokenType.ERC1155) {
IERC1155(escrow.buyerAssets[i].tokenAddress).safeTransferFrom(address(this), escrow.counterParty, escrow.buyerAssets[i].tokenId, escrow.buyerAssets[i].amount, "");
}
}
voidEscrow(agreementId);
}
function finalizeEscrow(bytes32 agreementId) internal nonReentrant {
Escrow storage escrow = LexScrowStorage.getEscrow(agreementId);
// Check all conditions before proceeding
if(block.timestamp > escrow.expiry) revert DealExpired();
if(escrow.status != EscrowStatus.PAID) revert EscrowNotPaid();
// Update state before external calls
escrow.status = EscrowStatus.FINALIZED;
emit DealFinalizedAt(agreementId, LexScrowStorage.getDealRegistry(), block.timestamp);
// Transfer buyer assets to company
for(uint256 i = 0; i < escrow.buyerAssets.length; i++) {
if(escrow.buyerAssets[i].tokenType == TokenType.ERC20) {
IERC20(escrow.buyerAssets[i].tokenAddress).transfer(ICyberCorp(LexScrowStorage.getCorp()).companyPayable(), escrow.buyerAssets[i].amount);
}
else if(escrow.buyerAssets[i].tokenType == TokenType.ERC721) {
IERC721(escrow.buyerAssets[i].tokenAddress).safeTransferFrom(address(this), ICyberCorp(LexScrowStorage.getCorp()).companyPayable(), escrow.buyerAssets[i].tokenId);
}
else if(escrow.buyerAssets[i].tokenType == TokenType.ERC1155) {
IERC1155(escrow.buyerAssets[i].tokenAddress).safeTransferFrom(address(this), ICyberCorp(LexScrowStorage.getCorp()).companyPayable(), escrow.buyerAssets[i].tokenId, escrow.buyerAssets[i].amount, "");
}
}
// Transfer corp assets to counter party
for(uint256 i = 0; i < escrow.corpAssets.length; i++) {
if(escrow.corpAssets[i].tokenType == TokenType.ERC20) {
IERC20(escrow.corpAssets[i].tokenAddress).transfer(escrow.counterParty, escrow.corpAssets[i].amount);
}
else if(escrow.corpAssets[i].tokenType == TokenType.ERC721) {
IERC721(escrow.corpAssets[i].tokenAddress).safeTransferFrom(address(this), escrow.counterParty, escrow.corpAssets[i].tokenId);
}
else if(escrow.corpAssets[i].tokenType == TokenType.ERC1155) {
IERC1155(escrow.corpAssets[i].tokenAddress).safeTransferFrom(address(this), escrow.counterParty, escrow.corpAssets[i].tokenId, escrow.corpAssets[i].amount, "");
}
}
}
function conditionCheck(bytes32 agreementId) public view returns (bool) {
ICondition[] storage conditions = LexScrowStorage.getConditionsByEscrow(agreementId);
//convert bytes32 to bytes
bytes memory agreementIdBytes = abi.encodePacked(agreementId);
for(uint256 i = 0; i < conditions.length; i++) {
if(!ICondition(conditions[i]).checkCondition(address(this), msg.sig, agreementIdBytes))
return false;
}
return true;
}
function voidEscrow(bytes32 agreementId) internal {
Escrow storage escrow = LexScrowStorage.getEscrow(agreementId);
escrow.status = EscrowStatus.VOIDED;
emit DealVoidedAt(agreementId, LexScrowStorage.getDealRegistry(), block.timestamp);
}
function getEscrowDetails(bytes32 agreementId) public view returns (Escrow memory) {
return LexScrowStorage.getEscrow(agreementId);
}
//receiver erc721s
function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4) {
return this.onERC721Received.selector;
}
//receiver erc1155s
function onERC1155Received(address operator, address from, uint256 tokenId, uint256 amount, bytes calldata data) external returns (bytes4) {
return this.onERC1155Received.selector;
}
}
DealManagerStorage.sol 111 lines
/* .o.
.888.
.8"888.
.8' `888.
.88ooo8888.
.8' `888.
o88o o8888o
ooo ooooo . ooooo ooooooo ooooo
`88. .888' .o8 `888' `8888 d8'
888b d'888 .ooooo. .o888oo .oooo. 888 .ooooo. Y888..8P
8 Y88. .P 888 d88' `88b 888 `P )88b 888 d88' `88b `8888'
8 `888' 888 888ooo888 888 .oP"888 888 888ooo888 .8PY888.
8 Y 888 888 .o 888 . d8( 888 888 o 888 .o d8' `888b
o8o o888o `Y8bod8P' "888" `Y888""8o o888ooooood8 `Y8bod8P' o888o o88888o
.oooooo. .o8 .oooooo.
d8P' `Y8b "888 d8P' `Y8b
888 oooo ooo 888oooo. .ooooo. oooo d8b 888 .ooooo. oooo d8b oo.ooooo.
888 `88. .8' d88' `88b d88' `88b `888""8P 888 d88' `88b `888""8P 888' `88b
888 `88..8' 888 888 888ooo888 888 888 888 888 888 888 888
`88b ooo `888' 888 888 888 .o 888 `88b ooo 888 888 888 888 888 .o.
`Y8bood8P' .8' `Y8bod8P' `Y8bod8P' d888b `Y8bood8P' `Y8bod8P' d888b 888bod8P' Y8P
.o..P' 888
`Y8P' o888o
_______________________________________________________________________________________________________
All software, documentation and other files and information in this repository (collectively, the "Software")
are copyright MetaLeX Labs, Inc., a Delaware corporation.
All rights reserved.
The Software is proprietary and shall not, in part or in whole, be used, copied, modified, merged, published,
distributed, transmitted, sublicensed, sold, or otherwise used in any form or by any means, electronic or
mechanical, including photocopying, recording, or by any information storage and retrieval system,
except with the express prior written permission of the copyright holder.*/
pragma solidity 0.8.28;
import "../interfaces/IIssuanceManager.sol";
/// @title DealManagerStorage
/// @notice Storage library for the DealManager contract that handles persistent data storage
/// @dev Uses the unstructured storage pattern to manage deal-related data
library DealManagerStorage {
// Storage slot for our struct
bytes32 constant STORAGE_POSITION = keccak256("cybercorp.deal.manager.storage.v1");
/// @notice Main storage layout struct that holds all deal manager data
/// @dev Uses unstructured storage pattern to avoid storage collisions
struct DealManagerData {
/// @notice Reference to the issuance manager contract
IIssuanceManager issuanceManager;
address upgradeFactory;
/// @notice Mapping from agreement IDs to their counter party values
mapping(bytes32 => string[]) counterPartyValues;
}
/// @notice Retrieves the storage reference for the DealManagerData struct
/// @dev Uses assembly to compute the storage position
/// @return ds Reference to the DealManagerData struct in storage
function dealManagerStorage() internal pure returns (DealManagerData storage ds) {
bytes32 position = STORAGE_POSITION;
assembly {
ds.slot := position
}
}
/// @notice Retrieves counter party values for a specific agreement
/// @dev Accesses the storage mapping directly
/// @param agreementId The unique identifier of the agreement
/// @return string[] Array of counter party values
function getCounterPartyValues(bytes32 agreementId) internal view returns (string[] storage) {
return dealManagerStorage().counterPartyValues[agreementId];
}
/// @notice Retrieves the current issuance manager
/// @dev Returns the stored issuance manager reference
/// @return IIssuanceManager The current issuance manager contract
function getIssuanceManager() internal view returns (IIssuanceManager) {
return dealManagerStorage().issuanceManager;
}
/// @notice Sets counter party values for a specific agreement
/// @dev Updates the storage mapping with new values
/// @param agreementId The unique identifier of the agreement
/// @param values Array of counter party values to store
function setCounterPartyValues(bytes32 agreementId, string[] memory values) internal {
dealManagerStorage().counterPartyValues[agreementId] = values;
}
/// @notice Updates the issuance manager reference
/// @dev Sets a new issuance manager contract address
/// @param _issuanceManager Address of the new issuance manager contract
function setIssuanceManager(address _issuanceManager) internal {
dealManagerStorage().issuanceManager = IIssuanceManager(_issuanceManager);
}
function setUpgradeFactory(address _upgradeFactory) internal {
dealManagerStorage().upgradeFactory = _upgradeFactory;
}
function getUpgradeFactory() external view returns (address) {
return dealManagerStorage().upgradeFactory;
}
}
BorgAuthStorage.sol 70 lines
/* .o.
.888.
.8"888.
.8' `888.
.88ooo8888.
.8' `888.
o88o o8888o
ooo ooooo . ooooo ooooooo ooooo
`88. .888' .o8 `888' `8888 d8'
888b d'888 .ooooo. .o888oo .oooo. 888 .ooooo. Y888..8P
8 Y88. .P 888 d88' `88b 888 `P )88b 888 d88' `88b `8888'
8 `888' 888 888ooo888 888 .oP"888 888 888ooo888 .8PY888.
8 Y 888 888 .o 888 . d8( 888 888 o 888 .o d8' `888b
o8o o888o `Y8bod8P' "888" `Y888""8o o888ooooood8 `Y8bod8P' o888o o88888o
.oooooo. .o8 .oooooo.
d8P' `Y8b "888 d8P' `Y8b
888 oooo ooo 888oooo. .ooooo. oooo d8b 888 .ooooo. oooo d8b oo.ooooo.
888 `88. .8' d88' `88b d88' `88b `888""8P 888 d88' `88b `888""8P 888' `88b
888 `88..8' 888 888 888ooo888 888 888 888 888 888 888 888
`88b ooo `888' 888 888 888 .o 888 `88b ooo 888 888 888 888 888 .o.
`Y8bood8P' .8' `Y8bod8P' `Y8bod8P' d888b `Y8bood8P' `Y8bod8P' d888b 888bod8P' Y8P
.o..P' 888
`Y8P' o888o
_______________________________________________________________________________________________________
All software, documentation and other files and information in this repository (collectively, the "Software")
are copyright MetaLeX Labs, Inc., a Delaware corporation.
All rights reserved.
The Software is proprietary and shall not, in part or in whole, be used, copied, modified, merged, published,
distributed, transmitted, sublicensed, sold, or otherwise used in any form or by any means, electronic or
mechanical, including photocopying, recording, or by any information storage and retrieval system,
except with the express prior written permission of the copyright holder.*/
pragma solidity 0.8.28;
library BorgAuthStorage {
// Storage slot for our struct
bytes32 constant STORAGE_POSITION = keccak256("cybercorp.borgauth.storage.v1");
// Main storage layout struct
struct BorgAuthData {
address AUTH;
}
// Returns the storage layout
function borgAuthStorage() internal pure returns (BorgAuthData storage ds) {
bytes32 position = STORAGE_POSITION;
assembly {
ds.slot := position
}
}
// Getters
function getAuth() internal view returns (address) {
return borgAuthStorage().AUTH;
}
// Setters
function setAuth(address _auth) internal {
borgAuthStorage().AUTH = _auth;
}
}
IAuthAdapter.sol 47 lines
/* .o.
.888.
.8"888.
.8' `888.
.88ooo8888.
.8' `888.
o88o o8888o
ooo ooooo . ooooo ooooooo ooooo
`88. .888' .o8 `888' `8888 d8'
888b d'888 .ooooo. .o888oo .oooo. 888 .ooooo. Y888..8P
8 Y88. .P 888 d88' `88b 888 `P )88b 888 d88' `88b `8888'
8 `888' 888 888ooo888 888 .oP"888 888 888ooo888 .8PY888.
8 Y 888 888 .o 888 . d8( 888 888 o 888 .o d8' `888b
o8o o888o `Y8bod8P' "888" `Y888""8o o888ooooood8 `Y8bod8P' o888o o88888o
.oooooo. .o8 .oooooo.
d8P' `Y8b "888 d8P' `Y8b
888 oooo ooo 888oooo. .ooooo. oooo d8b 888 .ooooo. oooo d8b oo.ooooo.
888 `88. .8' d88' `88b d88' `88b `888""8P 888 d88' `88b `888""8P 888' `88b
888 `88..8' 888 888 888ooo888 888 888 888 888 888 888 888
`88b ooo `888' 888 888 888 .o 888 `88b ooo 888 888 888 888 888 .o.
`Y8bood8P' .8' `Y8bod8P' `Y8bod8P' d888b `Y8bood8P' `Y8bod8P' d888b 888bod8P' Y8P
.o..P' 888
`Y8P' o888o
_______________________________________________________________________________________________________
All software, documentation and other files and information in this repository (collectively, the "Software")
are copyright MetaLeX Labs, Inc., a Delaware corporation.
All rights reserved.
The Software is proprietary and shall not, in part or in whole, be used, copied, modified, merged, published,
distributed, transmitted, sublicensed, sold, or otherwise used in any form or by any means, electronic or
mechanical, including photocopying, recording, or by any information storage and retrieval system,
except with the express prior written permission of the copyright holder.*/
pragma solidity ^0.8.28;
//Adapter interface for custom auth roles. Allows extensibility for different auth protocols i.e. hats.
interface IAuthAdapter {
function isAuthorized(address user) external view returns (uint256);
}
IERC1967.sol 24 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1967.sol)
pragma solidity ^0.8.20;
/**
* @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.
*/
interface IERC1967 {
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Emitted when the beacon is changed.
*/
event BeaconUpgraded(address indexed beacon);
}
Address.sol 150 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.2.0) (utils/Address.sol)
pragma solidity ^0.8.20;
import {Errors} from "./Errors.sol";
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert Errors.InsufficientBalance(address(this).balance, amount);
}
(bool success, bytes memory returndata) = recipient.call{value: amount}("");
if (!success) {
_revert(returndata);
}
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {Errors.FailedCall} error.
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert Errors.InsufficientBalance(address(this).balance, value);
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case
* of an unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {Errors.FailedCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}.
*/
function _revert(bytes memory returndata) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly ("memory-safe") {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert Errors.FailedCall();
}
}
}
StorageSlot.sol 143 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
pragma solidity ^0.8.20;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC-1967 implementation slot:
* ```solidity
* contract ERC1967 {
* // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(newImplementation.code.length > 0);
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*
* TIP: Consider using this library along with {SlotDerivation}.
*/
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
struct Int256Slot {
int256 value;
}
struct StringSlot {
string value;
}
struct BytesSlot {
bytes value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `Int256Slot` with member `value` located at `slot`.
*/
function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `StringSlot` with member `value` located at `slot`.
*/
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` representation of the string storage pointer `store`.
*/
function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
assembly ("memory-safe") {
r.slot := store.slot
}
}
/**
* @dev Returns a `BytesSlot` with member `value` located at `slot`.
*/
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
*/
function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
assembly ("memory-safe") {
r.slot := store.slot
}
}
}
Context.sol 28 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
IERC721.sol 135 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC-721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
* a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC-721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must have been allowed to move this token by either {approve} or
* {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
* a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721
* or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
* understand this adds an external call which potentially creates a reentrancy vulnerability.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the address zero.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
IERC721Enumerable.sol 29 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Enumerable.sol)
pragma solidity ^0.8.20;
import {IERC721} from "../IERC721.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Enumerable is IERC721 {
/**
* @dev Returns the total amount of tokens stored by the contract.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns a token ID owned by `owner` at a given `index` of its token list.
* Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);
/**
* @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
* Use along with {totalSupply} to enumerate all tokens.
*/
function tokenByIndex(uint256 index) external view returns (uint256);
}
IERC721Metadata.sol 27 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)
pragma solidity ^0.8.20;
import {IERC721} from "../IERC721.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Metadata is IERC721 {
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
}
ICyberCorp.sol 70 lines
/* .o.
.888.
.8"888.
.8' `888.
.88ooo8888.
.8' `888.
o88o o8888o
ooo ooooo . ooooo ooooooo ooooo
`88. .888' .o8 `888' `8888 d8'
888b d'888 .ooooo. .o888oo .oooo. 888 .ooooo. Y888..8P
8 Y88. .P 888 d88' `88b 888 `P )88b 888 d88' `88b `8888'
8 `888' 888 888ooo888 888 .oP"888 888 888ooo888 .8PY888.
8 Y 888 888 .o 888 . d8( 888 888 o 888 .o d8' `888b
o8o o888o `Y8bod8P' "888" `Y888""8o o888ooooood8 `Y8bod8P' o888o o88888o
.oooooo. .o8 .oooooo.
d8P' `Y8b "888 d8P' `Y8b
888 oooo ooo 888oooo. .ooooo. oooo d8b 888 .ooooo. oooo d8b oo.ooooo.
888 `88. .8' d88' `88b d88' `88b `888""8P 888 d88' `88b `888""8P 888' `88b
888 `88..8' 888 888 888ooo888 888 888 888 888 888 888 888
`88b ooo `888' 888 888 888 .o 888 `88b ooo 888 888 888 888 888 .o.
`Y8bood8P' .8' `Y8bod8P' `Y8bod8P' d888b `Y8bood8P' `Y8bod8P' d888b 888bod8P' Y8P
.o..P' 888
`Y8P' o888o
_______________________________________________________________________________________________________
All software, documentation and other files and information in this repository (collectively, the "Software")
are copyright MetaLeX Labs, Inc., a Delaware corporation.
All rights reserved.
The Software is proprietary and shall not, in part or in whole, be used, copied, modified, merged, published,
distributed, transmitted, sublicensed, sold, or otherwise used in any form or by any means, electronic or
mechanical, including photocopying, recording, or by any information storage and retrieval system,
except with the express prior written permission of the copyright holder.*/
import {CompanyOfficer} from "../CyberCorpConstants.sol";
pragma solidity 0.8.28;
interface ICyberCorp {
function initialize(
address _auth,
string memory _cyberCORPName,
string memory _cyberCORPType,
string memory _cyberCORPJurisdiction,
string memory _cyberCORPContactDetails,
string memory _defaultDisputeResolution,
address _issuanceManager,
address _companyPayable,
CompanyOfficer memory _officer,
address _upgradeFactory
) external;
function cyberCORPName() external view returns (string memory);
function cyberCORPJurisdiction() external view returns (string memory);
function cyberCORPContactDetails() external view returns (string memory);
function defaultDisputeResolution() external view returns (string memory);
function companyPayable() external view returns (address);
function companyOfficers() external view returns (address[] memory);
function cyberCORPType() external view returns (string memory);
function dealManager() external view returns (address);
function setDealManager(address _dealManager) external;
}
ITransferRestrictionHook.sol 60 lines
/* .o.
.888.
.8"888.
.8' `888.
.88ooo8888.
.8' `888.
o88o o8888o
ooo ooooo . ooooo ooooooo ooooo
`88. .888' .o8 `888' `8888 d8'
888b d'888 .ooooo. .o888oo .oooo. 888 .ooooo. Y888..8P
8 Y88. .P 888 d88' `88b 888 `P )88b 888 d88' `88b `8888'
8 `888' 888 888ooo888 888 .oP"888 888 888ooo888 .8PY888.
8 Y 888 888 .o 888 . d8( 888 888 o 888 .o d8' `888b
o8o o888o `Y8bod8P' "888" `Y888""8o o888ooooood8 `Y8bod8P' o888o o88888o
.oooooo. .o8 .oooooo.
d8P' `Y8b "888 d8P' `Y8b
888 oooo ooo 888oooo. .ooooo. oooo d8b 888 .ooooo. oooo d8b oo.ooooo.
888 `88. .8' d88' `88b d88' `88b `888""8P 888 d88' `88b `888""8P 888' `88b
888 `88..8' 888 888 888ooo888 888 888 888 888 888 888 888
`88b ooo `888' 888 888 888 .o 888 `88b ooo 888 888 888 888 888 .o.
`Y8bood8P' .8' `Y8bod8P' `Y8bod8P' d888b `Y8bood8P' `Y8bod8P' d888b 888bod8P' Y8P
.o..P' 888
`Y8P' o888o
_______________________________________________________________________________________________________
All software, documentation and other files and information in this repository (collectively, the "Software")
are copyright MetaLeX Labs, Inc., a Delaware corporation.
All rights reserved.
The Software is proprietary and shall not, in part or in whole, be used, copied, modified, merged, published,
distributed, transmitted, sublicensed, sold, or otherwise used in any form or by any means, electronic or
mechanical, including photocopying, recording, or by any information storage and retrieval system,
except with the express prior written permission of the copyright holder.*/
pragma solidity 0.8.28;
/// @title ITransferRestrictionHook
/// @notice Interface for transfer restriction hooks
interface ITransferRestrictionHook {
/// @notice Check if a transfer is allowed
/// @param from The address tokens are being transferred from
/// @param to The address tokens are being transferred to
/// @param tokenId The ID of the token being transferred
/// @param data Additional data passed to the hook
/// @return allowed Whether the transfer is allowed
/// @return reason The reason if the transfer is not allowed
function checkTransferRestriction(
address from,
address to,
uint256 tokenId,
bytes memory data
) external view returns (bool allowed, string memory reason);
}
CyberCorpConstants.sol 113 lines
/* .o.
.888.
.8"888.
.8' `888.
.88ooo8888.
.8' `888.
o88o o8888o
ooo ooooo . ooooo ooooooo ooooo
`88. .888' .o8 `888' `8888 d8'
888b d'888 .ooooo. .o888oo .oooo. 888 .ooooo. Y888..8P
8 Y88. .P 888 d88' `88b 888 `P )88b 888 d88' `88b `8888'
8 `888' 888 888ooo888 888 .oP"888 888 888ooo888 .8PY888.
8 Y 888 888 .o 888 . d8( 888 888 o 888 .o d8' `888b
o8o o888o `Y8bod8P' "888" `Y888""8o o888ooooood8 `Y8bod8P' o888o o88888o
.oooooo. .o8 .oooooo.
d8P' `Y8b "888 d8P' `Y8b
888 oooo ooo 888oooo. .ooooo. oooo d8b 888 .ooooo. oooo d8b oo.ooooo.
888 `88. .8' d88' `88b d88' `88b `888""8P 888 d88' `88b `888""8P 888' `88b
888 `88..8' 888 888 888ooo888 888 888 888 888 888 888 888
`88b ooo `888' 888 888 888 .o 888 `88b ooo 888 888 888 888 888 .o.
`Y8bood8P' .8' `Y8bod8P' `Y8bod8P' d888b `Y8bood8P' `Y8bod8P' d888b 888bod8P' Y8P
.o..P' 888
`Y8P' o888o
_______________________________________________________________________________________________________
All software, documentation and other files and information in this repository (collectively, the "Software")
are copyright MetaLeX Labs, Inc., a Delaware corporation.
All rights reserved.
The Software is proprietary and shall not, in part or in whole, be used, copied, modified, merged, published,
distributed, transmitted, sublicensed, sold, or otherwise used in any form or by any means, electronic or
mechanical, including photocopying, recording, or by any information storage and retrieval system,
except with the express prior written permission of the copyright holder.*/
pragma solidity 0.8.28;
enum SecurityClass {
SAFE,
SAFT,
SAFTE,
TokenPurchaseAgreement,
TokenWarrant,
ConvertibleNote,
CommonStock,
StockOption,
PreferredStock,
RestrictedStockPurchaseAgreement,
RestrictedStockUnit,
RestrictedTokenPurchaseAgreement,
RestrictedTokenUnit
}
enum SecuritySeries {
SeriesPreSeed,
SeriesSeed,
SeriesA,
SeriesB,
SeriesC,
SeriesD,
SeriesE,
SeriesF,
NA
}
enum SecurityStatus {
Unassigned,
Assigned,
Void
}
struct CompanyOfficer {
address eoa;
string name;
string contact;
string title;
}
enum ExercisePriceMethod {
perToken,
perWarrant
}
enum TokenCalculationMethod {
equityProRataToCompanyReserve,
equityProRataToTokenSupply
}
enum UnlockStartTimeType {
tokenWarrentTime,
tgeTime,
setTime
}
enum UnlockingIntervalType {
blockly,
secondly,
hourly,
daily,
monthly
}
CyberCertPrinterStorage.sol 185 lines
/* .o.
.888.
.8"888.
.8' `888.
.88ooo8888.
.8' `888.
o88o o8888o
ooo ooooo . ooooo ooooooo ooooo
`88. .888' .o8 `888' `8888 d8'
888b d'888 .ooooo. .o888oo .oooo. 888 .ooooo. Y888..8P
8 Y88. .P 888 d88' `88b 888 `P )88b 888 d88' `88b `8888'
8 `888' 888 888ooo888 888 .oP"888 888 888ooo888 .8PY888.
8 Y 888 888 .o 888 . d8( 888 888 o 888 .o d8' `888b
o8o o888o `Y8bod8P' "888" `Y888""8o o888ooooood8 `Y8bod8P' o888o o88888o
.oooooo. .o8 .oooooo.
d8P' `Y8b "888 d8P' `Y8b
888 oooo ooo 888oooo. .ooooo. oooo d8b 888 .ooooo. oooo d8b oo.ooooo.
888 `88. .8' d88' `88b d88' `88b `888""8P 888 d88' `88b `888""8P 888' `88b
888 `88..8' 888 888 888ooo888 888 888 888 888 888 888 888
`88b ooo `888' 888 888 888 .o 888 `88b ooo 888 888 888 888 888 .o.
`Y8bood8P' .8' `Y8bod8P' `Y8bod8P' d888b `Y8bood8P' `Y8bod8P' d888b 888bod8P' Y8P
.o..P' 888
`Y8P' o888o
_______________________________________________________________________________________________________
All software, documentation and other files and information in this repository (collectively, the "Software")
are copyright MetaLeX Labs, Inc., a Delaware corporation.
All rights reserved.
The Software is proprietary and shall not, in part or in whole, be used, copied, modified, merged, published,
distributed, transmitted, sublicensed, sold, or otherwise used in any form or by any means, electronic or
mechanical, including photocopying, recording, or by any information storage and retrieval system,
except with the express prior written permission of the copyright holder.*/
pragma solidity 0.8.28;
import "../CyberCorpConstants.sol";
import "../interfaces/ITransferRestrictionHook.sol";
import "./extensions/ICertificateExtension.sol";
struct CertificateDetails {
string signingOfficerName;
string signingOfficerTitle;
uint256 investmentAmountUSD;
uint256 issuerUSDValuationAtTimeOfInvestment;
uint256 unitsRepresented;
string legalDetails;
bytes extensionData;
}
struct Endorsement {
address endorser;
uint256 timestamp;
bytes signatureHash;
address registry; //optional
bytes32 agreementId; //optional
address endorsee;
string endorseeName;
}
struct OwnerDetails {
string name;
address ownerAddress;
}
library CyberCertPrinterStorage {
// Storage slot for our struct
bytes32 constant STORAGE_POSITION = keccak256("cybercorp.cert.printer.storage.v1");
// Main storage layout struct
struct CyberCertStorage {
// Token data
mapping(uint256 => CertificateDetails) certificateDetails;
mapping(uint256 => Endorsement[]) endorsements;
mapping(uint256 => OwnerDetails) owners;
mapping(uint256 => SecurityStatus) securityStatus;
mapping(uint256 => string[]) certLegend;
// Restriction hooks
mapping(uint256 => ITransferRestrictionHook) restrictionHooksById;
ITransferRestrictionHook globalRestrictionHook;
address extension;
// Contract configuration - making these public
address issuanceManager;
SecurityClass securityType;
SecuritySeries securitySeries;
string certificateUri;
string[] defaultLegend;
bool transferable;
bool endorsementRequired;
}
// Returns the storage layout
function cyberCertStorage() internal pure returns (CyberCertStorage storage s) {
bytes32 position = STORAGE_POSITION;
assembly {
s.slot := position
}
}
// Internal getters for complex types
function getCertificateDetails(uint256 tokenId) internal view returns (CertificateDetails storage) {
return cyberCertStorage().certificateDetails[tokenId];
}
function getEndorsements(uint256 tokenId) internal view returns (Endorsement[] storage) {
return cyberCertStorage().endorsements[tokenId];
}
function getOwnerDetails(uint256 tokenId) internal view returns (OwnerDetails storage) {
return cyberCertStorage().owners[tokenId];
}
function getSecurityStatus(uint256 tokenId) internal view returns (SecurityStatus) {
return cyberCertStorage().securityStatus[tokenId];
}
// Setters
function setCertificateDetails(uint256 tokenId, CertificateDetails memory details) internal {
cyberCertStorage().certificateDetails[tokenId] = details;
}
function addEndorsement(uint256 tokenId, Endorsement memory endorsement) internal {
cyberCertStorage().endorsements[tokenId].push(endorsement);
}
function setOwnerDetails(uint256 tokenId, OwnerDetails memory details) internal {
cyberCertStorage().owners[tokenId] = details;
}
function setSecurityStatus(uint256 tokenId, SecurityStatus status) internal {
cyberCertStorage().securityStatus[tokenId] = status;
}
// Configuration setters
function setIssuanceManager(address _issuanceManager) internal {
cyberCertStorage().issuanceManager = _issuanceManager;
}
function setCertificateUri(string memory _certificateUri) internal {
cyberCertStorage().certificateUri = _certificateUri;
}
function setTransferable(bool _transferable) internal {
cyberCertStorage().transferable = _transferable;
}
function setRestrictionHook(uint256 tokenId, ITransferRestrictionHook hook) internal {
cyberCertStorage().restrictionHooksById[tokenId] = hook;
}
function setGlobalRestrictionHook(ITransferRestrictionHook hook) internal {
cyberCertStorage().globalRestrictionHook = hook;
}
// Update the getter/setter for defaultLegend
function getDefaultLegend() internal view returns (string[] memory) {
return cyberCertStorage().defaultLegend;
}
function setDefaultLegend(string[] memory _defaultLegend) internal {
cyberCertStorage().defaultLegend = _defaultLegend;
}
// Extension management
function setExtension(uint256 tokenId, address extension) internal {
cyberCertStorage().extension = extension;
}
function getExtension(uint256 tokenId) internal view returns (address) {
return cyberCertStorage().extension;
}
function _getExtensionData(uint256 tokenId) internal view returns (bytes memory) {
return cyberCertStorage().certificateDetails[tokenId].extensionData;
}
}
IERC20.sol 79 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
IERC1155.sol 123 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC1155/IERC1155.sol)
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC-1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[ERC].
*/
interface IERC1155 is IERC165 {
/**
* @dev Emitted when `value` amount of tokens of type `id` are transferred from `from` to `to` by `operator`.
*/
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
/**
* @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
* transfers.
*/
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
/**
* @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
* `approved`.
*/
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
/**
* @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
*
* If an {URI} event was emitted for `id`, the standard
* https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
* returned by {IERC1155MetadataURI-uri}.
*/
event URI(string value, uint256 indexed id);
/**
* @dev Returns the value of tokens of token type `id` owned by `account`.
*/
function balanceOf(address account, uint256 id) external view returns (uint256);
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(
address[] calldata accounts,
uint256[] calldata ids
) external view returns (uint256[] memory);
/**
* @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the zero address.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address account, address operator) external view returns (bool);
/**
* @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`.
*
* WARNING: This function can potentially allow a reentrancy attack when transferring tokens
* to an untrusted contract, when invoking {IERC1155Receiver-onERC1155Received} on the receiver.
* Ensure to follow the checks-effects-interactions pattern and consider employing
* reentrancy guards when interacting with untrusted contracts.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
* - `from` must have a balance of tokens of type `id` of at least `value` amount.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external;
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
*
* WARNING: This function can potentially allow a reentrancy attack when transferring tokens
* to an untrusted contract, when invoking {IERC1155Receiver-onERC1155BatchReceived} on the receiver.
* Ensure to follow the checks-effects-interactions pattern and consider employing
* reentrancy guards when interacting with untrusted contracts.
*
* Emits either a {TransferSingle} or a {TransferBatch} event, depending on the length of the array arguments.
*
* Requirements:
*
* - `ids` and `values` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external;
}
ICyberAgreementRegistry.sol 180 lines
/* .o.
.888.
.8"888.
.8' `888.
.88ooo8888.
.8' `888.
o88o o8888o
ooo ooooo . ooooo ooooooo ooooo
`88. .888' .o8 `888' `8888 d8'
888b d'888 .ooooo. .o888oo .oooo. 888 .ooooo. Y888..8P
8 Y88. .P 888 d88' `88b 888 `P )88b 888 d88' `88b `8888'
8 `888' 888 888ooo888 888 .oP"888 888 888ooo888 .8PY888.
8 Y 888 888 .o 888 . d8( 888 888 o 888 .o d8' `888b
o8o o888o `Y8bod8P' "888" `Y888""8o o888ooooood8 `Y8bod8P' o888o o88888o
.oooooo. .o8 .oooooo.
d8P' `Y8b "888 d8P' `Y8b
888 oooo ooo 888oooo. .ooooo. oooo d8b 888 .ooooo. oooo d8b oo.ooooo.
888 `88. .8' d88' `88b d88' `88b `888""8P 888 d88' `88b `888""8P 888' `88b
888 `88..8' 888 888 888ooo888 888 888 888 888 888 888 888
`88b ooo `888' 888 888 888 .o 888 `88b ooo 888 888 888 888 888 .o.
`Y8bood8P' .8' `Y8bod8P' `Y8bod8P' d888b `Y8bood8P' `Y8bod8P' d888b 888bod8P' Y8P
.o..P' 888
`Y8P' o888o
_______________________________________________________________________________________________________
All software, documentation and other files and information in this repository (collectively, the "Software")
are copyright MetaLeX Labs, Inc., a Delaware corporation.
All rights reserved.
The Software is proprietary and shall not, in part or in whole, be used, copied, modified, merged, published,
distributed, transmitted, sublicensed, sold, or otherwise used in any form or by any means, electronic or
mechanical, including photocopying, recording, or by any information storage and retrieval system,
except with the express prior written permission of the copyright holder.*/
pragma solidity ^0.8.0;
interface ICyberAgreementRegistry {
struct Template {
string legalContractUri;
string title;
string[] globalFields;
string[] partyFields;
}
struct ContractData {
bytes32 templateId;
string[] globalValues;
address[] parties;
uint256 numSignatures;
bytes32 transactionHash;
}
event TemplateCreated(
bytes32 indexed templateId,
string indexed title,
string legalContractUri,
string[] globalFields,
string[] signerFields
);
event ContractCreated(
bytes32 indexed contractId,
bytes32 indexed templateId,
address[] parties
);
event AgreementSigned(
bytes32 indexed contractId,
address indexed party,
uint256 timestamp
);
event ContractFullySigned(bytes32 indexed contractId, uint256 timestamp);
function createTemplate(
bytes32 templateId,
string memory title,
string memory legalContractUri,
string[] memory globalFields,
string[] memory partyFields
) external;
function createContract(
bytes32 templateId,
uint256 salt,
string[] memory globalValues,
address[] memory parties,
string[][] memory partyValues,
bytes32 secretHash,
address finalizer,
uint256 expiry
) external returns (bytes32);
function signContract(
bytes32 contractId,
string[] memory partyValues,
bool fillUnallocated,
string memory secret
) external;
function signContractFor(
address signer,
bytes32 contractId,
string[] memory partyValues,
bytes calldata signature,
bool fillUnallocated, // to fill a 0 address or not
string memory secret
) external;
//function voidContractFor(bytes32 contractId, address party, bytes calldata signature) public {
function voidContractFor(
bytes32 contractId,
address party,
bytes calldata signature
) external;
function finalizeContract(bytes32 contractId) external;
function getParties(bytes32 contractId) external view returns (address[] memory);
function hasSigned(bytes32 contractId, address signer) external view returns (bool);
function getSignatureTimestamp(bytes32 contractId, address signer) external view returns (uint256);
function allPartiesSigned(bytes32 contractId) external view returns (bool);
function getContractDetails(
bytes32 contractId
)
external
view
returns (
bytes32 templateId,
string memory legalContractUri,
string[] memory globalFields,
string[] memory partyFields,
string[] memory globalValues,
address[] memory parties,
string[][] memory partyValues,
uint256[] memory signedAt,
uint256 numSignatures,
bool isComplete,
bytes32 transactionHash
);
function getTemplateDetails(
bytes32 templateId
)
external
view
returns (
string memory legalContractUri,
string[] memory globalFields,
string[] memory signerFields
);
function getSignerValues(
bytes32 contractId,
address signer
) external view returns (string[] memory signerValues);
function isVoided(bytes32 contractId) external view returns (bool);
function getAgreementsForParty(address party) external view returns (bytes32[] memory);
function getContractJson(bytes32 contractId) external view returns (string memory);
function getContractTransactionHash(bytes32 contractId) external view returns (bytes32);
function isFinalized(bytes32 contractId) external view returns (bool);
function allPartiesFinalized(bytes32 contractId) external view returns (bool);
}
ICyberCertPrinter.sol 124 lines
/* .o.
.888.
.8"888.
.8' `888.
.88ooo8888.
.8' `888.
o88o o8888o
ooo ooooo . ooooo ooooooo ooooo
`88. .888' .o8 `888' `8888 d8'
888b d'888 .ooooo. .o888oo .oooo. 888 .ooooo. Y888..8P
8 Y88. .P 888 d88' `88b 888 `P )88b 888 d88' `88b `8888'
8 `888' 888 888ooo888 888 .oP"888 888 888ooo888 .8PY888.
8 Y 888 888 .o 888 . d8( 888 888 o 888 .o d8' `888b
o8o o888o `Y8bod8P' "888" `Y888""8o o888ooooood8 `Y8bod8P' o888o o88888o
.oooooo. .o8 .oooooo.
d8P' `Y8b "888 d8P' `Y8b
888 oooo ooo 888oooo. .ooooo. oooo d8b 888 .ooooo. oooo d8b oo.ooooo.
888 `88. .8' d88' `88b d88' `88b `888""8P 888 d88' `88b `888""8P 888' `88b
888 `88..8' 888 888 888ooo888 888 888 888 888 888 888 888
`88b ooo `888' 888 888 888 .o 888 `88b ooo 888 888 888 888 888 .o.
`Y8bood8P' .8' `Y8bod8P' `Y8bod8P' d888b `Y8bood8P' `Y8bod8P' d888b 888bod8P' Y8P
.o..P' 888
`Y8P' o888o
_______________________________________________________________________________________________________
All software, documentation and other files and information in this repository (collectively, the "Software")
are copyright MetaLeX Labs, Inc., a Delaware corporation.
All rights reserved.
The Software is proprietary and shall not, in part or in whole, be used, copied, modified, merged, published,
distributed, transmitted, sublicensed, sold, or otherwise used in any form or by any means, electronic or
mechanical, including photocopying, recording, or by any information storage and retrieval system,
except with the express prior written permission of the copyright holder.*/
pragma solidity 0.8.28;
import "./IIssuanceManager.sol";
import "../CyberCorpConstants.sol";
interface ICyberCertPrinter {
function initialize(
string[] memory defaultLegend,
string memory name,
string memory ticker,
string memory _certificateUri,
address _issuanceManager,
SecurityClass _securityType,
SecuritySeries _securitySeries,
address _extension
) external;
function updateIssuanceManager(address _issuanceManager) external;
function updateDefaultLegend(string[] memory _ledger) external;
function defaultLegend() external view returns (string[] memory);
function setRestrictionHook(uint256 _id, address _hookAddress) external;
function setGlobalRestrictionHook(address hookAddress) external;
function safeMint(
uint256 tokenId,
address to,
CertificateDetails memory details
) external returns (uint256);
function setGlobalTransferable(bool _transferable) external;
function safeMintAndAssign(
address to,
uint256 tokenId,
CertificateDetails memory details
) external returns (uint256);
function assignCert(
address from,
uint256 tokenId,
address to,
CertificateDetails memory details
) external returns (uint256);
function addIssuerSignature(
uint256 tokenId,
string calldata signatureURI
) external;
function addEndorsement(
uint256 tokenId,
Endorsement memory newEndorsement
) external;
function endorseAndTransfer(
uint256 tokenId,
Endorsement memory newEndorsement,
address from,
address to
) external;
function updateCertificateDetails(
uint256 tokenId,
CertificateDetails calldata details
) external;
function burn(uint256 tokenId) external;
function voidCert(uint256 tokenId) external;
function getCertificateDetails(
uint256 tokenId
) external view returns (CertificateDetails memory);
function addCertLegend(uint256 tokenId, string memory newLegend) external;
function removeCertLegendAt(uint256 tokenId, uint256 index) external;
function addDefaultLegend(string memory newLegend) external;
function removeDefaultLegendAt(uint256 index) external;
function getEndorsementHistory(
uint256 tokenId,
uint256 index
)
external
view
returns (
address endorser,
string memory endorseeName,
address registry,
bytes32 agreementId,
uint256 timestamp,
bytes memory signatureHash,
address endorsee
);
function tokenURI(uint256 tokenId) external view returns (string memory);
function totalSupply() external view returns (uint256);
}
ICondition.sol 46 lines
/* .o.
.888.
.8"888.
.8' `888.
.88ooo8888.
.8' `888.
o88o o8888o
ooo ooooo . ooooo ooooooo ooooo
`88. .888' .o8 `888' `8888 d8'
888b d'888 .ooooo. .o888oo .oooo. 888 .ooooo. Y888..8P
8 Y88. .P 888 d88' `88b 888 `P )88b 888 d88' `88b `8888'
8 `888' 888 888ooo888 888 .oP"888 888 888ooo888 .8PY888.
8 Y 888 888 .o 888 . d8( 888 888 o 888 .o d8' `888b
o8o o888o `Y8bod8P' "888" `Y888""8o o888ooooood8 `Y8bod8P' o888o o88888o
.oooooo. .o8 .oooooo.
d8P' `Y8b "888 d8P' `Y8b
888 oooo ooo 888oooo. .ooooo. oooo d8b 888 .ooooo. oooo d8b oo.ooooo.
888 `88. .8' d88' `88b d88' `88b `888""8P 888 d88' `88b `888""8P 888' `88b
888 `88..8' 888 888 888ooo888 888 888 888 888 888 888 888
`88b ooo `888' 888 888 888 .o 888 `88b ooo 888 888 888 888 888 .o.
`Y8bood8P' .8' `Y8bod8P' `Y8bod8P' d888b `Y8bood8P' `Y8bod8P' d888b 888bod8P' Y8P
.o..P' 888
`Y8P' o888o
_______________________________________________________________________________________________________
All software, documentation and other files and information in this repository (collectively, the "Software")
are copyright MetaLeX Labs, Inc., a Delaware corporation.
All rights reserved.
The Software is proprietary and shall not, in part or in whole, be used, copied, modified, merged, published,
distributed, transmitted, sublicensed, sold, or otherwise used in any form or by any means, electronic or
mechanical, including photocopying, recording, or by any information storage and retrieval system,
except with the express prior written permission of the copyright holder.*/
pragma solidity ^0.8.20;
interface ICondition {
function checkCondition(address _contract, bytes4 _functionSignature, bytes memory data) external view returns (bool);
}
ReentrancyGuard.sol 87 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_status = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}
LexScrowStorage.sol 139 lines
/* .o.
.888.
.8"888.
.8' `888.
.88ooo8888.
.8' `888.
o88o o8888o
ooo ooooo . ooooo ooooooo ooooo
`88. .888' .o8 `888' `8888 d8'
888b d'888 .ooooo. .o888oo .oooo. 888 .ooooo. Y888..8P
8 Y88. .P 888 d88' `88b 888 `P )88b 888 d88' `88b `8888'
8 `888' 888 888ooo888 888 .oP"888 888 888ooo888 .8PY888.
8 Y 888 888 .o 888 . d8( 888 888 o 888 .o d8' `888b
o8o o888o `Y8bod8P' "888" `Y888""8o o888ooooood8 `Y8bod8P' o888o o88888o
.oooooo. .o8 .oooooo.
d8P' `Y8b "888 d8P' `Y8b
888 oooo ooo 888oooo. .ooooo. oooo d8b 888 .ooooo. oooo d8b oo.ooooo.
888 `88. .8' d88' `88b d88' `88b `888""8P 888 d88' `88b `888""8P 888' `88b
888 `88..8' 888 888 888ooo888 888 888 888 888 888 888 888
`88b ooo `888' 888 888 888 .o 888 `88b ooo 888 888 888 888 888 .o.
`Y8bood8P' .8' `Y8bod8P' `Y8bod8P' d888b `Y8bood8P' `Y8bod8P' d888b 888bod8P' Y8P
.o..P' 888
`Y8P' o888o
_______________________________________________________________________________________________________
All software, documentation and other files and information in this repository (collectively, the "Software")
are copyright MetaLeX Labs, Inc., a Delaware corporation.
All rights reserved.
The Software is proprietary and shall not, in part or in whole, be used, copied, modified, merged, published,
distributed, transmitted, sublicensed, sold, or otherwise used in any form or by any means, electronic or
mechanical, including photocopying, recording, or by any information storage and retrieval system,
except with the express prior written permission of the copyright holder.*/
pragma solidity 0.8.28;
import "../interfaces/ICondition.sol";
enum TokenType {
ERC20,
ERC721,
ERC1155
}
enum EscrowStatus {
PENDING,
PAID,
FINALIZED,
VOIDED
}
struct Token {
TokenType tokenType;
address tokenAddress;
uint256 tokenId;
uint256 amount;
}
struct Escrow {
bytes32 agreementId;
address counterParty;
Token[] corpAssets;
Token[] buyerAssets;
bytes signature;
uint256 expiry;
EscrowStatus status;
}
library LexScrowStorage {
// Storage slot for our struct
bytes32 constant STORAGE_POSITION = keccak256("cybercorp.lexscrow.storage.v1");
// Main storage layout struct
struct LexScrowData {
address CORP;
address DEAL_REGISTRY;
mapping(bytes32 => Escrow) escrows;
mapping(bytes32 => ICondition[]) conditionsByEscrow;
}
// Returns the storage layout
function lexScrowStorage() internal pure returns (LexScrowData storage ds) {
bytes32 position = STORAGE_POSITION;
assembly {
ds.slot := position
}
}
// Getters
function getCorp() internal view returns (address) {
return lexScrowStorage().CORP;
}
function getDealRegistry() internal view returns (address) {
return lexScrowStorage().DEAL_REGISTRY;
}
function getEscrow(bytes32 agreementId) internal view returns (Escrow storage) {
return lexScrowStorage().escrows[agreementId];
}
function getConditionsByEscrow(bytes32 agreementId) internal view returns (ICondition[] storage) {
return lexScrowStorage().conditionsByEscrow[agreementId];
}
// Setters
function setCorp(address _corp) internal {
lexScrowStorage().CORP = _corp;
}
function setDealRegistry(address _dealRegistry) internal {
lexScrowStorage().DEAL_REGISTRY = _dealRegistry;
}
function setEscrow(bytes32 agreementId, Escrow memory escrow) internal {
lexScrowStorage().escrows[agreementId] = escrow;
}
function addConditionToEscrow(bytes32 agreementId, ICondition condition) internal {
lexScrowStorage().conditionsByEscrow[agreementId].push(condition);
}
function removeConditionFromEscrow(bytes32 agreementId, uint256 index) internal {
ICondition[] storage conditions = lexScrowStorage().conditionsByEscrow[agreementId];
require(index < conditions.length, "Index out of bounds");
for (uint i = index; i < conditions.length - 1; i++) {
conditions[i] = conditions[i + 1];
}
conditions.pop();
}
}
IERC165.sol 25 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
ICertificateExtension.sol 47 lines
/* .o.
.888.
.8"888.
.8' `888.
.88ooo8888.
.8' `888.
o88o o8888o
ooo ooooo . ooooo ooooooo ooooo
`88. .888' .o8 `888' `8888 d8'
888b d'888 .ooooo. .o888oo .oooo. 888 .ooooo. Y888..8P
8 Y88. .P 888 d88' `88b 888 `P )88b 888 d88' `88b `8888'
8 `888' 888 888ooo888 888 .oP"888 888 888ooo888 .8PY888.
8 Y 888 888 .o 888 . d8( 888 888 o 888 .o d8' `888b
o8o o888o `Y8bod8P' "888" `Y888""8o o888ooooood8 `Y8bod8P' o888o o88888o
.oooooo. .o8 .oooooo.
d8P' `Y8b "888 d8P' `Y8b
888 oooo ooo 888oooo. .ooooo. oooo d8b 888 .ooooo. oooo d8b oo.ooooo.
888 `88. .8' d88' `88b d88' `88b `888""8P 888 d88' `88b `888""8P 888' `88b
888 `88..8' 888 888 888ooo888 888 888 888 888 888 888 888
`88b ooo `888' 888 888 888 .o 888 `88b ooo 888 888 888 888 888 .o.
`Y8bood8P' .8' `Y8bod8P' `Y8bod8P' d888b `Y8bood8P' `Y8bod8P' d888b 888bod8P' Y8P
.o..P' 888
`Y8P' o888o
_______________________________________________________________________________________________________
All software, documentation and other files and information in this repository (collectively, the "Software")
are copyright MetaLeX Labs, Inc., a Delaware corporation.
All rights reserved.
The Software is proprietary and shall not, in part or in whole, be used, copied, modified, merged, published,
distributed, transmitted, sublicensed, sold, or otherwise used in any form or by any means, electronic or
mechanical, including photocopying, recording, or by any information storage and retrieval system,
except with the express prior written permission of the copyright holder.*/
pragma solidity 0.8.28;
interface ICertificateExtension {
function supportsExtensionType(bytes32 extensionType) external pure returns (bool);
function getExtensionURI(bytes memory data) external view returns (string memory);
}
Read Contract
AUTH 0x0a5623fb → address
beacon 0x59659e90 → address
computeDealManagerAddress 0x48c57f0f → address
getBeaconImplementation 0xc6a188ca → address
userRoles 0x74d5e100 → uint256
Write Contract 3 functions
These functions modify contract state and require a wallet transaction to execute.
deployDealManager 0x66f76474
bytes32 _salt
returns: address
initialize 0xc4d66de8
address _auth
upgradeImplementation 0x83f94db7
address _newImplementation
Recent Transactions
No transactions found for this address