Source Code
Overview
GLMR Balance
GLMR Value
$0.00Latest 22 from a total of 22 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| 0xa1001a60 | 1196952 | 1329 days ago | IN | 0 GLMR | 0.02758414 | ||||
| 0xa1001a60 | 987271 | 1359 days ago | IN | 0 GLMR | 0.02758292 | ||||
| 0xa1001a60 | 987185 | 1359 days ago | IN | 0 GLMR | 0.02759389 | ||||
| Update Bulla Tag | 957341 | 1364 days ago | IN | 0 GLMR | 0.00601357 | ||||
| 0xa1001a60 | 939913 | 1366 days ago | IN | 0 GLMR | 0.02759267 | ||||
| 0xa1001a60 | 862548 | 1377 days ago | IN | 0 GLMR | 0.0258493 | ||||
| 0xa1001a60 | 862523 | 1377 days ago | IN | 0 GLMR | 0.02584321 | ||||
| 0xa1001a60 | 844784 | 1380 days ago | IN | 0 GLMR | 0.0312009 | ||||
| 0xa1001a60 | 819520 | 1384 days ago | IN | 0 GLMR | 0.0271681 | ||||
| 0xa1001a60 | 819486 | 1384 days ago | IN | 0 GLMR | 0.02757562 | ||||
| 0xa1001a60 | 819425 | 1384 days ago | IN | 0 GLMR | 0.02758049 | ||||
| 0xa1001a60 | 785495 | 1388 days ago | IN | 0 GLMR | 0.02758901 | ||||
| Update Bulla Tag | 762316 | 1392 days ago | IN | 0 GLMR | 0.01148488 | ||||
| Update Bulla Tag | 762314 | 1392 days ago | IN | 0 GLMR | 0.01167835 | ||||
| 0xa1001a60 | 760569 | 1392 days ago | IN | 0 GLMR | 0.02760241 | ||||
| 0xa1001a60 | 679614 | 1404 days ago | IN | 0 GLMR | 0.02758171 | ||||
| 0xa1001a60 | 472361 | 1433 days ago | IN | 0 GLMR | 0.0254769 | ||||
| 0xa1001a60 | 472304 | 1433 days ago | IN | 0 GLMR | 0.0254781 | ||||
| 0xa1001a60 | 472289 | 1433 days ago | IN | 0 GLMR | 0.0254745 | ||||
| 0xa1001a60 | 472119 | 1433 days ago | IN | 0 GLMR | 0.0254793 | ||||
| 0xa1001a60 | 472113 | 1433 days ago | IN | 0 GLMR | 0.0271861 | ||||
| 0xa1001a60 | 472039 | 1433 days ago | IN | 0 GLMR | 0.0294569 |
View more zero value Internal Transactions in Advanced View mode
Cross-Chain Transactions
Loading...
Loading
Contract Name:
BullaBanker
Compiler Version
v0.8.7+commit.e28d00a7
Contract Source Code (Solidity)
/**
*Submitted for verification at moonbeam.moonscan.io on 2022-04-20
*/
//SPDX-License-Identifier: BUSL-1.1
// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) 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 `amount` 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 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @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);
}
// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [////IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
/**
* @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://diligence.consensys.net/posts/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.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @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, it is bubbled up by this
* function (like regular Solidity function calls).
*
* 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.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @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`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// 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 {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
pragma solidity ^0.8.3;
////import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
struct FeeInfo {
address collectionAddress;
uint32 feeBasisPoints;
uint32 bullaTokenThreshold; //# of BULLA tokens held to get fee reduction
uint32 reducedFeeBasisPoints; //reduced fee for BULLA token holders
}
interface IBullaManager {
event FeeChanged(
address indexed bullaManager,
uint256 prevFee,
uint256 newFee,
uint256 blocktime
);
event CollectorChanged(
address indexed bullaManager,
address prevCollector,
address newCollector,
uint256 blocktime
);
event OwnerChanged(
address indexed bullaManager,
address prevOwner,
address newOwner,
uint256 blocktime
);
event BullaTokenChanged(
address indexed bullaManager,
address prevBullaToken,
address newBullaToken,
uint256 blocktime
);
event FeeThresholdChanged(
address indexed bullaManager,
uint256 prevFeeThreshold,
uint256 newFeeThreshold,
uint256 blocktime
);
event ReducedFeeChanged(
address indexed bullaManager,
uint256 prevFee,
uint256 newFee,
uint256 blocktime
);
function setOwner(address _owner) external;
function setFee(uint32 _feeBasisPoints) external;
function setCollectionAddress(address _collectionAddress) external;
function setbullaThreshold(uint32 _threshold) external;
function setReducedFee(uint32 reducedFeeBasisPoints) external;
function setBullaTokenAddress(address _bullaTokenAddress) external;
function getBullaBalance(address _holder) external view returns (uint256);
function getFeeInfo(address _holder)
external
view
returns (uint32, address);
function getTransactionFee(address _holder, uint paymentAmount) external view returns(address sendFeesTo, uint transactionFee);
}
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
////import "../IERC20.sol";
////import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @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;
}
}
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* 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[EIP 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);
}
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
////import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC721 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`, checking first that contract recipients
* are aware of the ERC721 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 be 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: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
*
* 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 Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @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 caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool _approved) external;
/**
* @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);
/**
* @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;
}
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
////import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)
pragma solidity ^0.8.0;
////import "../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);
}
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
// OpenZeppelin Contracts v4.4.1 (token/ERC721/ERC721.sol)
pragma solidity ^0.8.0;
////import "./IERC721.sol";
////import "./IERC721Receiver.sol";
////import "./extensions/IERC721Metadata.sol";
////import "../../utils/Address.sol";
////import "../../utils/Context.sol";
////import "../../utils/Strings.sol";
////import "../../utils/introspection/ERC165.sol";
/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
* the Metadata extension, but not including the Enumerable extension, which is available separately as
* {ERC721Enumerable}.
*/
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Mapping from token ID to owner address
mapping(uint256 => address) private _owners;
// Mapping owner address to token count
mapping(address => uint256) private _balances;
// Mapping from token ID to approved address
mapping(uint256 => address) private _tokenApprovals;
// Mapping from owner to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721-balanceOf}.
*/
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _balances[owner];
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "ERC721: owner query for nonexistent token");
return owner;
}
/**
* @dev See {IERC721Metadata-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
/**
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overriden in child contracts.
*/
function _baseURI() internal view virtual returns (string memory) {
return "";
}
/**
* @dev See {IERC721-approve}.
*/
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not owner nor approved for all"
);
_approve(to, tokenId);
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransfer(from, to, tokenId, _data);
}
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* `_data` is additional data, it has no specified format and it is sent in call to `to`.
*
* This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
* implement alternative mechanisms to perform token transfer, such as signature-based.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
/**
* @dev Returns whether `tokenId` exists.
*
* Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
*
* Tokens start existing when they are minted (`_mint`),
* and stop existing when they are burned (`_burn`).
*/
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _owners[tokenId] != address(0);
}
/**
* @dev Returns whether `spender` is allowed to manage `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
}
/**
* @dev Safely mints `tokenId` and transfers it to `to`.
*
* Requirements:
*
* - `tokenId` must not exist.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeMint(
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
/**
* @dev Mints `tokenId` and transfers it to `to`.
*
* WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
*
* Requirements:
*
* - `tokenId` must not exist.
* - `to` cannot be the zero address.
*
* Emits a {Transfer} event.
*/
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
// Clear approvals
_approve(address(0), tokenId);
_balances[owner] -= 1;
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
* As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
*
* Emits a {Transfer} event.
*/
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
// Clear approvals from the previous owner
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* Emits a {Approval} event.
*/
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits a {ApprovalForAll} event.
*/
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC721: approve to caller");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
* The call is not executed if the target address is not a contract.
*
* @param from address representing the previous owner of the given token ID
* @param to target address that will receive the tokens
* @param tokenId uint256 ID of the token to be transferred
* @param _data bytes optional data to send along with the call
* @return bool whether the call correctly returned the expected magic value
*/
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, ``from``'s `tokenId` will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
}
// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)
pragma solidity ^0.8.0;
/**
* @title Counters
* @author Matt Condon (@shrugs)
* @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
* of elements in a mapping, issuing ERC721 ids, or counting request ids.
*
* Include with `using Counters for Counters.Counter;`
*/
library Counters {
struct Counter {
// This variable should never be directly accessed by users of the library: interactions must be restricted to
// the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
// this feature: see https://github.com/ethereum/solidity/issues/4637
uint256 _value; // default: 0
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
unchecked {
counter._value += 1;
}
}
function decrement(Counter storage counter) internal {
uint256 value = counter._value;
require(value > 0, "Counter: decrement overflow");
unchecked {
counter._value = value - 1;
}
}
function reset(Counter storage counter) internal {
counter._value = 0;
}
}
pragma solidity ^0.8.7;
////import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
////import "./IBullaManager.sol";
struct Multihash {
bytes32 hash;
uint8 hashFunction;
uint8 size;
}
enum Status {
Pending,
Repaying,
Paid,
Rejected,
Rescinded
}
struct Claim {
uint256 claimAmount;
uint256 paidAmount;
Status status;
uint256 dueBy;
address debtor;
address claimToken;
Multihash attachment;
}
interface IBullaClaim {
event ClaimCreated(
address bullaManager,
uint256 indexed tokenId,
address parent,
address indexed creditor,
address indexed debtor,
address origin,
string description,
Claim claim,
uint256 blocktime
);
event ClaimPayment(
address indexed bullaManager,
uint256 indexed tokenId,
address indexed debtor,
address paidBy,
address paidByOrigin,
uint256 paymentAmount,
uint256 blocktime
);
event ClaimRejected(
address indexed bullaManager,
uint256 indexed tokenId,
uint256 blocktime
);
event ClaimRescinded(
address indexed bullaManager,
uint256 indexed tokenId,
uint256 blocktime
);
event FeePaid(
address indexed bullaManager,
uint256 indexed tokenId,
address indexed collectionAddress,
uint256 paymentAmount,
uint256 transactionFee,
uint256 blocktime
);
event BullaManagerSet(
address indexed prevBullaManager,
address indexed newBullaManager,
uint256 blocktime
);
function createClaim(
address creditor,
address debtor,
string memory description,
uint256 claimAmount,
uint256 dueBy,
address claimToken,
Multihash calldata attachment
) external returns (uint256 newTokenId);
function createClaimWithURI(
address creditor,
address debtor,
string memory description,
uint256 claimAmount,
uint256 dueBy,
address claimToken,
Multihash calldata attachment,
string calldata _tokenUri
) external returns (uint256 newTokenId);
function payClaim(uint256 tokenId, uint256 paymentAmount) external;
function rejectClaim(uint256 tokenId) external;
function rescindClaim(uint256 tokenId) external;
function getClaim(uint256 tokenId) external view returns (Claim calldata);
function bullaManager() external view returns (address);
}
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
pragma solidity ^0.8.0;
////import "../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.
*
* By default, the owner account will be the one that deploys the contract. 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;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing 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 {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_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);
}
}
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721URIStorage.sol)
pragma solidity ^0.8.0;
////import "../ERC721.sol";
/**
* @dev ERC721 token with storage based token URI management.
*/
abstract contract ERC721URIStorage is ERC721 {
using Strings for uint256;
// Optional mapping for token URIs
mapping(uint256 => string) private _tokenURIs;
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
string memory base = _baseURI();
// If there is no base URI, return the token URI.
if (bytes(base).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(base, _tokenURI));
}
return super.tokenURI(tokenId);
}
/**
* @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual override {
super._burn(tokenId);
if (bytes(_tokenURIs[tokenId]).length != 0) {
delete _tokenURIs[tokenId];
}
}
}
pragma solidity ^0.8.7;
////import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
////import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
////import "@openzeppelin/contracts/utils/Counters.sol";
////import "@openzeppelin/contracts/access/Ownable.sol";
////import "./interfaces/IBullaManager.sol";
////import "./interfaces/IBullaClaim.sol";
////import "@openzeppelin/contracts/utils/Counters.sol";
////import "@openzeppelin/contracts/utils/Address.sol";
error ZeroAddress();
error PastDueDate();
error TokenIdNoExist();
error ClaimTokenNotContract();
error NotCreditor(address sender);
error NotDebtor(address sender);
error NotTokenOwner(address sender);
error NotCreditorOrDebtor(address sender);
error OwnerNotCreditor(address sender);
error ClaimCompleted();
error ClaimNotPending();
error IncorrectValue(uint256 value, uint256 expectedValue);
error InsufficientBalance(uint256 senderBalance);
error InsufficientAllowance(uint256 senderAllowance);
error RepayingTooMuch(uint256 amount, uint256 expectedAmount);
error ValueMustBeGreaterThanZero();
abstract contract BullaClaimERC721URI is Ownable, ERC721URIStorage {
string public baseURI;
function setBaseURI(string memory baseURI_) public onlyOwner {
baseURI = baseURI_;
}
function _baseURI() internal view override returns (string memory) {
return baseURI;
}
}
contract BullaClaimERC721 is IBullaClaim, BullaClaimERC721URI {
using SafeERC20 for IERC20;
using Counters for Counters.Counter;
using Address for address;
Counters.Counter private tokenIds;
address public override bullaManager;
mapping(uint256 => Claim) private claimTokens;
modifier onlyTokenOwner(uint256 tokenId) {
if (ownerOf(tokenId) != msg.sender) revert NotCreditor(msg.sender);
_;
}
modifier onlyDebtor(uint256 tokenId) {
if (claimTokens[tokenId].debtor != msg.sender)
revert NotDebtor(msg.sender);
_;
}
modifier onlyIncompleteClaim(uint256 tokenId) {
if (
claimTokens[tokenId].status != Status.Pending &&
claimTokens[tokenId].status != Status.Repaying
) revert ClaimCompleted();
_;
}
modifier onlyPendingClaim(uint256 tokenId) {
if (claimTokens[tokenId].status != Status.Pending)
revert ClaimNotPending();
_;
}
constructor(address bullaManager_, string memory baseURI_)
ERC721("BullaClaim721", "CLAIM")
{
setBullaManager(bullaManager_);
setBaseURI(baseURI_);
}
function setBullaManager(address _bullaManager) public onlyOwner {
address prevBullaManager = bullaManager;
bullaManager = _bullaManager;
emit BullaManagerSet(prevBullaManager, bullaManager, block.timestamp);
}
function _createClaim(
address creditor,
address debtor,
string memory description,
uint256 claimAmount,
uint256 dueBy,
address claimToken,
Multihash calldata attachment
) internal returns (uint256) {
if (creditor == address(0) || debtor == address(0)) {
revert ZeroAddress();
}
if (claimAmount == 0) {
revert ValueMustBeGreaterThanZero();
}
if (dueBy < block.timestamp) {
revert PastDueDate();
}
if (!claimToken.isContract()) {
revert ClaimTokenNotContract();
}
tokenIds.increment();
uint256 newTokenId = tokenIds.current();
_safeMint(creditor, newTokenId);
Claim memory newClaim;
newClaim.debtor = debtor;
newClaim.claimAmount = claimAmount;
newClaim.dueBy = dueBy;
newClaim.status = Status.Pending;
newClaim.claimToken = claimToken;
newClaim.attachment = attachment;
claimTokens[newTokenId] = newClaim;
emit ClaimCreated(
bullaManager,
newTokenId,
msg.sender,
creditor,
debtor,
tx.origin,
description,
newClaim,
block.timestamp
);
return newTokenId;
}
function createClaim(
address creditor,
address debtor,
string memory description,
uint256 claimAmount,
uint256 dueBy,
address claimToken,
Multihash calldata attachment
) external override returns (uint256) {
uint256 _tokenId = _createClaim(
creditor,
debtor,
description,
claimAmount,
dueBy,
claimToken,
attachment
);
return _tokenId;
}
function createClaimWithURI(
address creditor,
address debtor,
string memory description,
uint256 claimAmount,
uint256 dueBy,
address claimToken,
Multihash calldata attachment,
string calldata _tokenUri
) external override returns (uint256) {
uint256 _tokenId = _createClaim(
creditor,
debtor,
description,
claimAmount,
dueBy,
claimToken,
attachment
);
_setTokenURI(_tokenId, _tokenUri);
return _tokenId;
}
function payClaim(uint256 tokenId, uint256 paymentAmount)
external
override
onlyIncompleteClaim(tokenId)
{
if (paymentAmount == 0) revert ValueMustBeGreaterThanZero();
if (!_exists(tokenId)) revert TokenIdNoExist();
Claim memory claim = getClaim(tokenId);
address creditor = ownerOf(tokenId);
uint256 amountToRepay = claim.claimAmount - claim.paidAmount;
uint256 totalPayment = paymentAmount >= amountToRepay
? amountToRepay
: paymentAmount;
claim.paidAmount + totalPayment == claim.claimAmount
? claim.status = Status.Paid
: claim.status = Status.Repaying;
claimTokens[tokenId].paidAmount += totalPayment;
claimTokens[tokenId].status = claim.status;
(address collectionAddress, uint256 transactionFee) = IBullaManager(
bullaManager
).getTransactionFee(msg.sender, totalPayment);
IERC20(claim.claimToken).safeTransferFrom(
msg.sender,
creditor,
totalPayment - transactionFee
);
if (transactionFee > 0) {
IERC20(claim.claimToken).safeTransferFrom(
msg.sender,
collectionAddress,
transactionFee
);
}
emit ClaimPayment(
bullaManager,
tokenId,
claim.debtor,
msg.sender,
tx.origin,
paymentAmount,
block.timestamp
);
emit FeePaid(
bullaManager,
tokenId,
collectionAddress,
paymentAmount,
transactionFee,
block.timestamp
);
}
function rejectClaim(uint256 tokenId)
external
override
onlyDebtor(tokenId)
onlyPendingClaim(tokenId)
{
claimTokens[tokenId].status = Status.Rejected;
emit ClaimRejected(bullaManager, tokenId, block.timestamp);
}
function rescindClaim(uint256 tokenId)
external
override
onlyTokenOwner(tokenId)
onlyPendingClaim(tokenId)
{
claimTokens[tokenId].status = Status.Rescinded;
emit ClaimRescinded(bullaManager, tokenId, block.timestamp);
}
function burn(uint256 tokenId) external onlyTokenOwner(tokenId) {
_burn(tokenId);
}
function nextClaimId() external view returns (uint256) {
return tokenIds.current() + 1;
}
function getClaim(uint256 tokenId)
public
view
override
returns (Claim memory)
{
return claimTokens[tokenId];
}
}
// OpenZeppelin Contracts v4.4.1 (proxy/Clones.sol)
pragma solidity ^0.8.0;
/**
* @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
* deploying minimal proxy contracts, also known as "clones".
*
* > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
* > a minimal bytecode implementation that delegates all calls to a known, fixed address.
*
* The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
* (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
* deterministic method.
*
* _Available since v3.4._
*/
library Clones {
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create opcode, which should never revert.
*/
function clone(address implementation) internal returns (address instance) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
instance := create(0, ptr, 0x37)
}
require(instance != address(0), "ERC1167: create failed");
}
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create2 opcode and a `salt` to deterministically deploy
* the clone. Using the same `implementation` and `salt` multiple time will revert, since
* the clones cannot be deployed twice at the same address.
*/
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
instance := create2(0, ptr, 0x37, salt)
}
require(instance != address(0), "ERC1167: create2 failed");
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000)
mstore(add(ptr, 0x38), shl(0x60, deployer))
mstore(add(ptr, 0x4c), salt)
mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))
predicted := keccak256(add(ptr, 0x37), 0x55)
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(address implementation, bytes32 salt)
internal
view
returns (address predicted)
{
return predictDeterministicAddress(implementation, salt, address(this));
}
}
pragma solidity ^0.8.7;
////import "@openzeppelin/contracts/proxy/Clones.sol";
////import "./interfaces/IBullaClaim.sol";
////import "./BullaClaimERC721.sol";
contract BullaBanker {
address public bullaClaimERC721;
event BullaTagUpdated(
address indexed bullaManager,
uint256 indexed tokenId,
address indexed updatedBy,
bytes32 tag,
uint256 blocktime
);
event BullaBankerCreated(
address indexed bullaManager,
address indexed bullaClaimERC721,
address bullaBanker,
uint256 blocktime
);
struct ClaimParams {
uint256 claimAmount;
address creditor;
address debtor;
string description;
uint256 dueBy;
address claimToken;
Multihash attachment;
}
constructor(address _bullaClaimERC721) {
bullaClaimERC721 = _bullaClaimERC721;
emit BullaBankerCreated(
IBullaClaim(_bullaClaimERC721).bullaManager(),
bullaClaimERC721,
address(this),
block.timestamp
);
}
function createBullaClaim(
ClaimParams calldata claim,
bytes32 bullaTag,
string calldata _tokenUri
) public returns (uint256) {
if (msg.sender != claim.creditor && msg.sender != claim.debtor)
revert NotCreditorOrDebtor(msg.sender);
address _bullaClaimERC721Address = bullaClaimERC721;
uint256 newTokenId = BullaClaimERC721(_bullaClaimERC721Address)
.createClaimWithURI(
claim.creditor,
claim.debtor,
claim.description,
claim.claimAmount,
claim.dueBy,
claim.claimToken,
claim.attachment,
_tokenUri
);
emit BullaTagUpdated(
IBullaClaim(_bullaClaimERC721Address).bullaManager(),
newTokenId,
msg.sender,
bullaTag,
block.timestamp
);
return newTokenId;
}
function updateBullaTag(uint256 tokenId, bytes32 newTag) public {
address _bullaClaimERC721Address = bullaClaimERC721;
BullaClaimERC721 _bullaClaimERC721 = BullaClaimERC721(
_bullaClaimERC721Address
);
address claimOwner = _bullaClaimERC721.ownerOf(tokenId);
Claim memory bullaClaim = _bullaClaimERC721.getClaim(tokenId);
if (msg.sender != claimOwner && msg.sender != bullaClaim.debtor)
revert NotCreditorOrDebtor(msg.sender);
emit BullaTagUpdated(
IBullaClaim(_bullaClaimERC721Address).bullaManager(),
tokenId,
msg.sender,
newTag,
block.timestamp
);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_bullaClaimERC721","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"NotCreditorOrDebtor","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"bullaManager","type":"address"},{"indexed":true,"internalType":"address","name":"bullaClaimERC721","type":"address"},{"indexed":false,"internalType":"address","name":"bullaBanker","type":"address"},{"indexed":false,"internalType":"uint256","name":"blocktime","type":"uint256"}],"name":"BullaBankerCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"bullaManager","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"updatedBy","type":"address"},{"indexed":false,"internalType":"bytes32","name":"tag","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"blocktime","type":"uint256"}],"name":"BullaTagUpdated","type":"event"},{"inputs":[],"name":"bullaClaimERC721","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"claimAmount","type":"uint256"},{"internalType":"address","name":"creditor","type":"address"},{"internalType":"address","name":"debtor","type":"address"},{"internalType":"string","name":"description","type":"string"},{"internalType":"uint256","name":"dueBy","type":"uint256"},{"internalType":"address","name":"claimToken","type":"address"},{"components":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"size","type":"uint8"}],"internalType":"struct Multihash","name":"attachment","type":"tuple"}],"internalType":"struct BullaBanker.ClaimParams","name":"claim","type":"tuple"},{"internalType":"bytes32","name":"bullaTag","type":"bytes32"},{"internalType":"string","name":"_tokenUri","type":"string"}],"name":"createBullaClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes32","name":"newTag","type":"bytes32"}],"name":"updateBullaTag","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b506040516200111b3803806200111b83398181016040528101906200003791906200019f565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16635e39986f6040518163ffffffff1660e01b815260040160206040518083038186803b158015620000f557600080fd5b505afa1580156200010a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200013091906200019f565b73ffffffffffffffffffffffffffffffffffffffff167fcd6cdcfa59baeeb6a8f29b9185692fde86556f2594d800e9ee55c1a3677e19e4304260405162000179929190620001f3565b60405180910390a3506200027d565b600081519050620001998162000263565b92915050565b600060208284031215620001b857620001b76200025e565b5b6000620001c88482850162000188565b91505092915050565b620001dc8162000220565b82525050565b620001ed8162000254565b82525050565b60006040820190506200020a6000830185620001d1565b620002196020830184620001e2565b9392505050565b60006200022d8262000234565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600080fd5b6200026e8162000220565b81146200027a57600080fd5b50565b610e8e806200028d6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80634fbb898714610046578063635ab94014610062578063a1001a6014610080575b600080fd5b610060600480360381019061005b9190610a1e565b6100b0565b005b61006a610391565b6040516100779190610b30565b60405180910390f35b61009a60048036038101906100959190610933565b6103b5565b6040516100a79190610c05565b60405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600081905060008173ffffffffffffffffffffffffffffffffffffffff16636352211e866040518263ffffffff1660e01b81526004016101169190610c05565b60206040518083038186803b15801561012e57600080fd5b505afa158015610142573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101669190610906565b905060008273ffffffffffffffffffffffffffffffffffffffff16635aef2447876040518263ffffffff1660e01b81526004016101a39190610c05565b6101206040518083038186803b1580156101bc57600080fd5b505afa1580156101d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101f491906109c3565b90508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156102625750806080015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b156102a457336040517fda107cfb00000000000000000000000000000000000000000000000000000000815260040161029b9190610b30565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16868573ffffffffffffffffffffffffffffffffffffffff16635e39986f6040518163ffffffff1660e01b815260040160206040518083038186803b15801561030257600080fd5b505afa158015610316573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061033a9190610906565b73ffffffffffffffffffffffffffffffffffffffff167f49f89b2b71540cd91d6f6db8f1a06ddb75ad4bbd125e70cf5eb12712ea886f338842604051610381929190610bdc565b60405180910390a4505050505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008460200160208101906103ca91906108d9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015610443575084604001602081019061041391906108d9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b1561048557336040517fda107cfb00000000000000000000000000000000000000000000000000000000815260040161047c9190610b30565b60405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff1663c92aeec18860200160208101906104dc91906108d9565b8960400160208101906104ef91906108d9565b8a80606001906104ff9190610c20565b8c600001358d608001358e60a001602081019061051c91906108d9565b8f60c0018e8e6040518b63ffffffff1660e01b81526004016105479a99989796959493929190610b4b565b602060405180830381600087803b15801561056157600080fd5b505af1158015610575573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059991906109f1565b90503373ffffffffffffffffffffffffffffffffffffffff16818373ffffffffffffffffffffffffffffffffffffffff16635e39986f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156105f957600080fd5b505afa15801561060d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106319190610906565b73ffffffffffffffffffffffffffffffffffffffff167f49f89b2b71540cd91d6f6db8f1a06ddb75ad4bbd125e70cf5eb12712ea886f338942604051610678929190610bdc565b60405180910390a48092505050949350505050565b60008135905061069c81610dec565b92915050565b6000815190506106b181610dec565b92915050565b6000813590506106c681610e03565b92915050565b6000815190506106db81610e03565b92915050565b6000815190506106f081610e1a565b92915050565b60008083601f84011261070c5761070b610dae565b5b8235905067ffffffffffffffff81111561072957610728610da9565b5b60208301915083600182028301111561074557610744610dc7565b5b9250929050565b6000610120828403121561076357610762610db8565b5b81905092915050565b6000610120828403121561078357610782610dbd565b5b61078d60e0610c83565b9050600061079d8482850161089a565b60008301525060206107b18482850161089a565b60208301525060406107c5848285016106e1565b60408301525060606107d98482850161089a565b60608301525060806107ed848285016106a2565b60808301525060a0610801848285016106a2565b60a08301525060c061081584828501610821565b60c08301525092915050565b60006060828403121561083757610836610dbd565b5b6108416060610c83565b90506000610851848285016106cc565b6000830152506020610865848285016108c4565b6020830152506040610879848285016108c4565b60408301525092915050565b60008135905061089481610e2a565b92915050565b6000815190506108a981610e2a565b92915050565b6000813590506108be81610e41565b92915050565b6000815190506108d381610e41565b92915050565b6000602082840312156108ef576108ee610dd6565b5b60006108fd8482850161068d565b91505092915050565b60006020828403121561091c5761091b610dd6565b5b600061092a848285016106a2565b91505092915050565b6000806000806060858703121561094d5761094c610dd6565b5b600085013567ffffffffffffffff81111561096b5761096a610dd1565b5b6109778782880161074c565b9450506020610988878288016106b7565b935050604085013567ffffffffffffffff8111156109a9576109a8610dd1565b5b6109b5878288016106f6565b925092505092959194509250565b600061012082840312156109da576109d9610dd6565b5b60006109e88482850161076c565b91505092915050565b600060208284031215610a0757610a06610dd6565b5b6000610a158482850161089a565b91505092915050565b60008060408385031215610a3557610a34610dd6565b5b6000610a4385828601610885565b9250506020610a54858286016106b7565b9150509250929050565b610a6781610ce7565b82525050565b610a7681610cf9565b82525050565b610a8581610cf9565b82525050565b6000610a978385610ca8565b9350610aa4838584610d3a565b610aad83610ddb565b840190509392505050565b60608201610ac96000830183610cb9565b610ad66000850182610a6d565b50610ae46020830183610cd0565b610af16020850182610b21565b50610aff6040830183610cd0565b610b0c6040850182610b21565b50505050565b610b1b81610d23565b82525050565b610b2a81610d2d565b82525050565b6000602082019050610b456000830184610a5e565b92915050565b600061014082019050610b61600083018d610a5e565b610b6e602083018c610a5e565b8181036040830152610b81818a8c610a8b565b9050610b906060830189610b12565b610b9d6080830188610b12565b610baa60a0830187610a5e565b610bb760c0830186610ab8565b818103610120830152610bcb818486610a8b565b90509b9a5050505050505050505050565b6000604082019050610bf16000830185610a7c565b610bfe6020830184610b12565b9392505050565b6000602082019050610c1a6000830184610b12565b92915050565b60008083356001602003843603038112610c3d57610c3c610dc2565b5b80840192508235915067ffffffffffffffff821115610c5f57610c5e610db3565b5b602083019250600182023603831315610c7b57610c7a610dcc565b5b509250929050565b6000610c8d610c9e565b9050610c998282610d49565b919050565b6000604051905090565b600082825260208201905092915050565b6000610cc860208401846106b7565b905092915050565b6000610cdf60208401846108af565b905092915050565b6000610cf282610d03565b9050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b610d5282610ddb565b810181811067ffffffffffffffff82111715610d7157610d70610d7a565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b610df581610ce7565b8114610e0057600080fd5b50565b610e0c81610cf9565b8114610e1757600080fd5b50565b60058110610e2757600080fd5b50565b610e3381610d23565b8114610e3e57600080fd5b50565b610e4a81610d2d565b8114610e5557600080fd5b5056fea2646970667358221220f94e5a289f24dcb719c7653973fc4231d015fbb1f84da8cfdec170908e06dfd464736f6c634300080700330000000000000000000000001c534661326b41c8b8aab5631eced6d9755ff192
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100415760003560e01c80634fbb898714610046578063635ab94014610062578063a1001a6014610080575b600080fd5b610060600480360381019061005b9190610a1e565b6100b0565b005b61006a610391565b6040516100779190610b30565b60405180910390f35b61009a60048036038101906100959190610933565b6103b5565b6040516100a79190610c05565b60405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600081905060008173ffffffffffffffffffffffffffffffffffffffff16636352211e866040518263ffffffff1660e01b81526004016101169190610c05565b60206040518083038186803b15801561012e57600080fd5b505afa158015610142573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101669190610906565b905060008273ffffffffffffffffffffffffffffffffffffffff16635aef2447876040518263ffffffff1660e01b81526004016101a39190610c05565b6101206040518083038186803b1580156101bc57600080fd5b505afa1580156101d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101f491906109c3565b90508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156102625750806080015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b156102a457336040517fda107cfb00000000000000000000000000000000000000000000000000000000815260040161029b9190610b30565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16868573ffffffffffffffffffffffffffffffffffffffff16635e39986f6040518163ffffffff1660e01b815260040160206040518083038186803b15801561030257600080fd5b505afa158015610316573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061033a9190610906565b73ffffffffffffffffffffffffffffffffffffffff167f49f89b2b71540cd91d6f6db8f1a06ddb75ad4bbd125e70cf5eb12712ea886f338842604051610381929190610bdc565b60405180910390a4505050505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008460200160208101906103ca91906108d9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015610443575084604001602081019061041391906108d9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b1561048557336040517fda107cfb00000000000000000000000000000000000000000000000000000000815260040161047c9190610b30565b60405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff1663c92aeec18860200160208101906104dc91906108d9565b8960400160208101906104ef91906108d9565b8a80606001906104ff9190610c20565b8c600001358d608001358e60a001602081019061051c91906108d9565b8f60c0018e8e6040518b63ffffffff1660e01b81526004016105479a99989796959493929190610b4b565b602060405180830381600087803b15801561056157600080fd5b505af1158015610575573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059991906109f1565b90503373ffffffffffffffffffffffffffffffffffffffff16818373ffffffffffffffffffffffffffffffffffffffff16635e39986f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156105f957600080fd5b505afa15801561060d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106319190610906565b73ffffffffffffffffffffffffffffffffffffffff167f49f89b2b71540cd91d6f6db8f1a06ddb75ad4bbd125e70cf5eb12712ea886f338942604051610678929190610bdc565b60405180910390a48092505050949350505050565b60008135905061069c81610dec565b92915050565b6000815190506106b181610dec565b92915050565b6000813590506106c681610e03565b92915050565b6000815190506106db81610e03565b92915050565b6000815190506106f081610e1a565b92915050565b60008083601f84011261070c5761070b610dae565b5b8235905067ffffffffffffffff81111561072957610728610da9565b5b60208301915083600182028301111561074557610744610dc7565b5b9250929050565b6000610120828403121561076357610762610db8565b5b81905092915050565b6000610120828403121561078357610782610dbd565b5b61078d60e0610c83565b9050600061079d8482850161089a565b60008301525060206107b18482850161089a565b60208301525060406107c5848285016106e1565b60408301525060606107d98482850161089a565b60608301525060806107ed848285016106a2565b60808301525060a0610801848285016106a2565b60a08301525060c061081584828501610821565b60c08301525092915050565b60006060828403121561083757610836610dbd565b5b6108416060610c83565b90506000610851848285016106cc565b6000830152506020610865848285016108c4565b6020830152506040610879848285016108c4565b60408301525092915050565b60008135905061089481610e2a565b92915050565b6000815190506108a981610e2a565b92915050565b6000813590506108be81610e41565b92915050565b6000815190506108d381610e41565b92915050565b6000602082840312156108ef576108ee610dd6565b5b60006108fd8482850161068d565b91505092915050565b60006020828403121561091c5761091b610dd6565b5b600061092a848285016106a2565b91505092915050565b6000806000806060858703121561094d5761094c610dd6565b5b600085013567ffffffffffffffff81111561096b5761096a610dd1565b5b6109778782880161074c565b9450506020610988878288016106b7565b935050604085013567ffffffffffffffff8111156109a9576109a8610dd1565b5b6109b5878288016106f6565b925092505092959194509250565b600061012082840312156109da576109d9610dd6565b5b60006109e88482850161076c565b91505092915050565b600060208284031215610a0757610a06610dd6565b5b6000610a158482850161089a565b91505092915050565b60008060408385031215610a3557610a34610dd6565b5b6000610a4385828601610885565b9250506020610a54858286016106b7565b9150509250929050565b610a6781610ce7565b82525050565b610a7681610cf9565b82525050565b610a8581610cf9565b82525050565b6000610a978385610ca8565b9350610aa4838584610d3a565b610aad83610ddb565b840190509392505050565b60608201610ac96000830183610cb9565b610ad66000850182610a6d565b50610ae46020830183610cd0565b610af16020850182610b21565b50610aff6040830183610cd0565b610b0c6040850182610b21565b50505050565b610b1b81610d23565b82525050565b610b2a81610d2d565b82525050565b6000602082019050610b456000830184610a5e565b92915050565b600061014082019050610b61600083018d610a5e565b610b6e602083018c610a5e565b8181036040830152610b81818a8c610a8b565b9050610b906060830189610b12565b610b9d6080830188610b12565b610baa60a0830187610a5e565b610bb760c0830186610ab8565b818103610120830152610bcb818486610a8b565b90509b9a5050505050505050505050565b6000604082019050610bf16000830185610a7c565b610bfe6020830184610b12565b9392505050565b6000602082019050610c1a6000830184610b12565b92915050565b60008083356001602003843603038112610c3d57610c3c610dc2565b5b80840192508235915067ffffffffffffffff821115610c5f57610c5e610db3565b5b602083019250600182023603831315610c7b57610c7a610dcc565b5b509250929050565b6000610c8d610c9e565b9050610c998282610d49565b919050565b6000604051905090565b600082825260208201905092915050565b6000610cc860208401846106b7565b905092915050565b6000610cdf60208401846108af565b905092915050565b6000610cf282610d03565b9050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b610d5282610ddb565b810181811067ffffffffffffffff82111715610d7157610d70610d7a565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b610df581610ce7565b8114610e0057600080fd5b50565b610e0c81610cf9565b8114610e1757600080fd5b50565b60058110610e2757600080fd5b50565b610e3381610d23565b8114610e3e57600080fd5b50565b610e4a81610d2d565b8114610e5557600080fd5b5056fea2646970667358221220f94e5a289f24dcb719c7653973fc4231d015fbb1f84da8cfdec170908e06dfd464736f6c63430008070033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001c534661326b41c8b8aab5631eced6d9755ff192
-----Decoded View---------------
Arg [0] : _bullaClaimERC721 (address): 0x1c534661326b41c8b8aab5631ECED6D9755ff192
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000001c534661326b41c8b8aab5631eced6d9755ff192
Deployed Bytecode Sourcemap
63303:2693:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65269:724;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63331:31;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64277:984;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65269:724;65344:32;65379:16;;;;;;;;;;;65344:51;;65406:34;65474:24;65406:103;;65522:18;65543:17;:25;;;65569:7;65543:34;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65522:55;;65588:23;65614:17;:26;;;65641:7;65614:35;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65588:61;;65678:10;65664:24;;:10;:24;;;;:59;;;;;65706:10;:17;;;65692:31;;:10;:31;;;;65664:59;65660:116;;;65765:10;65745:31;;;;;;;;;;;:::i;:::-;;;;;;;;65660:116;65913:10;65794:191;;65891:7;65836:24;65824:50;;;:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65794:191;;;65938:6;65959:15;65794:191;;;;;;;:::i;:::-;;;;;;;;65333:660;;;;65269:724;;:::o;63331:31::-;;;;;;;;;;;;:::o;64277:984::-;64426:7;64464:5;:14;;;;;;;;;;:::i;:::-;64450:28;;:10;:28;;;;:58;;;;;64496:5;:12;;;;;;;;;;:::i;:::-;64482:26;;:10;:26;;;;64450:58;64446:115;;;64550:10;64530:31;;;;;;;;;;;:::i;:::-;;;;;;;;64446:115;64574:32;64609:16;;;;;;;;;;;64574:51;;64636:18;64674:24;64657:75;;;64751:5;:14;;;;;;;;;;:::i;:::-;64784:5;:12;;;;;;;;;;:::i;:::-;64815:5;:17;;;;;;;;:::i;:::-;64851:5;:17;;;64887:5;:11;;;64917:5;:16;;;;;;;;;;:::i;:::-;64952:5;:16;;64987:9;;64657:354;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64636:375;;65151:10;65029:196;;65126:10;65071:24;65059:50;;;:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65029:196;;;65176:8;65199:15;65029:196;;;;;;;:::i;:::-;;;;;;;;65243:10;65236:17;;;;64277:984;;;;;;:::o;7:139:1:-;53:5;91:6;78:20;69:29;;107:33;134:5;107:33;:::i;:::-;7:139;;;;:::o;152:143::-;209:5;240:6;234:13;225:22;;256:33;283:5;256:33;:::i;:::-;152:143;;;;:::o;301:139::-;347:5;385:6;372:20;363:29;;401:33;428:5;401:33;:::i;:::-;301:139;;;;:::o;446:143::-;503:5;534:6;528:13;519:22;;550:33;577:5;550:33;:::i;:::-;446:143;;;;:::o;595:165::-;663:5;694:6;688:13;679:22;;710:44;748:5;710:44;:::i;:::-;595:165;;;;:::o;780:553::-;838:8;848:6;898:3;891:4;883:6;879:17;875:27;865:122;;906:79;;:::i;:::-;865:122;1019:6;1006:20;996:30;;1049:18;1041:6;1038:30;1035:117;;;1071:79;;:::i;:::-;1035:117;1185:4;1177:6;1173:17;1161:29;;1239:3;1231:4;1223:6;1219:17;1209:8;1205:32;1202:41;1199:128;;;1246:79;;:::i;:::-;1199:128;780:553;;;;;:::o;1377:236::-;1454:5;1495:3;1486:6;1481:3;1477:16;1473:26;1470:113;;;1502:79;;:::i;:::-;1470:113;1601:6;1592:15;;1377:236;;;;:::o;1639:1538::-;1722:5;1766:6;1754:9;1749:3;1745:19;1741:32;1738:119;;;1776:79;;:::i;:::-;1738:119;1875:21;1891:4;1875:21;:::i;:::-;1866:30;;1962:1;2002:60;2058:3;2049:6;2038:9;2034:22;2002:60;:::i;:::-;1995:4;1988:5;1984:16;1977:86;1906:168;2139:2;2180:60;2236:3;2227:6;2216:9;2212:22;2180:60;:::i;:::-;2173:4;2166:5;2162:16;2155:86;2084:168;2313:2;2354:71;2421:3;2412:6;2401:9;2397:22;2354:71;:::i;:::-;2347:4;2340:5;2336:16;2329:97;2262:175;2497:2;2538:60;2594:3;2585:6;2574:9;2570:22;2538:60;:::i;:::-;2531:4;2524:5;2520:16;2513:86;2447:163;2671:3;2713:60;2769:3;2760:6;2749:9;2745:22;2713:60;:::i;:::-;2706:4;2699:5;2695:16;2688:86;2620:165;2850:3;2892:60;2948:3;2939:6;2928:9;2924:22;2892:60;:::i;:::-;2885:4;2878:5;2874:16;2867:86;2795:169;3029:3;3071:87;3154:3;3145:6;3134:9;3130:22;3071:87;:::i;:::-;3064:4;3057:5;3053:16;3046:113;2974:196;1639:1538;;;;:::o;3207:785::-;3294:5;3338:4;3326:9;3321:3;3317:19;3313:30;3310:117;;;3346:79;;:::i;:::-;3310:117;3445:21;3461:4;3445:21;:::i;:::-;3436:30;;3525:1;3565:60;3621:3;3612:6;3601:9;3597:22;3565:60;:::i;:::-;3558:4;3551:5;3547:16;3540:86;3476:161;3704:2;3745:58;3799:3;3790:6;3779:9;3775:22;3745:58;:::i;:::-;3738:4;3731:5;3727:16;3720:84;3647:168;3874:2;3915:58;3969:3;3960:6;3949:9;3945:22;3915:58;:::i;:::-;3908:4;3901:5;3897:16;3890:84;3825:160;3207:785;;;;:::o;3998:139::-;4044:5;4082:6;4069:20;4060:29;;4098:33;4125:5;4098:33;:::i;:::-;3998:139;;;;:::o;4143:143::-;4200:5;4231:6;4225:13;4216:22;;4247:33;4274:5;4247:33;:::i;:::-;4143:143;;;;:::o;4292:135::-;4336:5;4374:6;4361:20;4352:29;;4390:31;4415:5;4390:31;:::i;:::-;4292:135;;;;:::o;4433:139::-;4488:5;4519:6;4513:13;4504:22;;4535:31;4560:5;4535:31;:::i;:::-;4433:139;;;;:::o;4578:329::-;4637:6;4686:2;4674:9;4665:7;4661:23;4657:32;4654:119;;;4692:79;;:::i;:::-;4654:119;4812:1;4837:53;4882:7;4873:6;4862:9;4858:22;4837:53;:::i;:::-;4827:63;;4783:117;4578:329;;;;:::o;4913:351::-;4983:6;5032:2;5020:9;5011:7;5007:23;5003:32;5000:119;;;5038:79;;:::i;:::-;5000:119;5158:1;5183:64;5239:7;5230:6;5219:9;5215:22;5183:64;:::i;:::-;5173:74;;5129:128;4913:351;;;;:::o;5270:1041::-;5390:6;5398;5406;5414;5463:2;5451:9;5442:7;5438:23;5434:32;5431:119;;;5469:79;;:::i;:::-;5431:119;5617:1;5606:9;5602:17;5589:31;5647:18;5639:6;5636:30;5633:117;;;5669:79;;:::i;:::-;5633:117;5774:84;5850:7;5841:6;5830:9;5826:22;5774:84;:::i;:::-;5764:94;;5560:308;5907:2;5933:53;5978:7;5969:6;5958:9;5954:22;5933:53;:::i;:::-;5923:63;;5878:118;6063:2;6052:9;6048:18;6035:32;6094:18;6086:6;6083:30;6080:117;;;6116:79;;:::i;:::-;6080:117;6229:65;6286:7;6277:6;6266:9;6262:22;6229:65;:::i;:::-;6211:83;;;;6006:298;5270:1041;;;;;;;:::o;6317:398::-;6410:6;6459:3;6447:9;6438:7;6434:23;6430:33;6427:120;;;6466:79;;:::i;:::-;6427:120;6586:1;6611:87;6690:7;6681:6;6670:9;6666:22;6611:87;:::i;:::-;6601:97;;6557:151;6317:398;;;;:::o;6721:351::-;6791:6;6840:2;6828:9;6819:7;6815:23;6811:32;6808:119;;;6846:79;;:::i;:::-;6808:119;6966:1;6991:64;7047:7;7038:6;7027:9;7023:22;6991:64;:::i;:::-;6981:74;;6937:128;6721:351;;;;:::o;7078:474::-;7146:6;7154;7203:2;7191:9;7182:7;7178:23;7174:32;7171:119;;;7209:79;;:::i;:::-;7171:119;7329:1;7354:53;7399:7;7390:6;7379:9;7375:22;7354:53;:::i;:::-;7344:63;;7300:117;7456:2;7482:53;7527:7;7518:6;7507:9;7503:22;7482:53;:::i;:::-;7472:63;;7427:118;7078:474;;;;;:::o;7558:118::-;7645:24;7663:5;7645:24;:::i;:::-;7640:3;7633:37;7558:118;;:::o;7682:108::-;7759:24;7777:5;7759:24;:::i;:::-;7754:3;7747:37;7682:108;;:::o;7796:118::-;7883:24;7901:5;7883:24;:::i;:::-;7878:3;7871:37;7796:118;;:::o;7944:304::-;8042:3;8063:71;8127:6;8122:3;8063:71;:::i;:::-;8056:78;;8144:43;8180:6;8175:3;8168:5;8144:43;:::i;:::-;8212:29;8234:6;8212:29;:::i;:::-;8207:3;8203:39;8196:46;;7944:304;;;;;:::o;8298:764::-;8451:4;8446:3;8442:14;8521:50;8565:4;8558:5;8554:16;8547:5;8521:50;:::i;:::-;8584:63;8641:4;8636:3;8632:14;8618:12;8584:63;:::i;:::-;8466:191;8730:48;8772:4;8765:5;8761:16;8754:5;8730:48;:::i;:::-;8791:59;8844:4;8839:3;8835:14;8821:12;8791:59;:::i;:::-;8667:193;8925:48;8967:4;8960:5;8956:16;8949:5;8925:48;:::i;:::-;8986:59;9039:4;9034:3;9030:14;9016:12;8986:59;:::i;:::-;8870:185;8420:642;8298:764;;:::o;9068:118::-;9155:24;9173:5;9155:24;:::i;:::-;9150:3;9143:37;9068:118;;:::o;9192:102::-;9265:22;9281:5;9265:22;:::i;:::-;9260:3;9253:35;9192:102;;:::o;9300:222::-;9393:4;9431:2;9420:9;9416:18;9408:26;;9444:71;9512:1;9501:9;9497:17;9488:6;9444:71;:::i;:::-;9300:222;;;;:::o;9528:1331::-;9933:4;9971:3;9960:9;9956:19;9948:27;;9985:71;10053:1;10042:9;10038:17;10029:6;9985:71;:::i;:::-;10066:72;10134:2;10123:9;10119:18;10110:6;10066:72;:::i;:::-;10185:9;10179:4;10175:20;10170:2;10159:9;10155:18;10148:48;10213:88;10296:4;10287:6;10279;10213:88;:::i;:::-;10205:96;;10311:72;10379:2;10368:9;10364:18;10355:6;10311:72;:::i;:::-;10393:73;10461:3;10450:9;10446:19;10437:6;10393:73;:::i;:::-;10476;10544:3;10533:9;10529:19;10520:6;10476:73;:::i;:::-;10559:129;10683:3;10672:9;10668:19;10659:6;10559:129;:::i;:::-;10736:9;10730:4;10726:20;10720:3;10709:9;10705:19;10698:49;10764:88;10847:4;10838:6;10830;10764:88;:::i;:::-;10756:96;;9528:1331;;;;;;;;;;;;;:::o;10865:332::-;10986:4;11024:2;11013:9;11009:18;11001:26;;11037:71;11105:1;11094:9;11090:17;11081:6;11037:71;:::i;:::-;11118:72;11186:2;11175:9;11171:18;11162:6;11118:72;:::i;:::-;10865:332;;;;;:::o;11203:222::-;11296:4;11334:2;11323:9;11319:18;11311:26;;11347:71;11415:1;11404:9;11400:17;11391:6;11347:71;:::i;:::-;11203:222;;;;:::o;11431:725::-;11509:4;11515:6;11571:11;11558:25;11671:1;11665:4;11661:12;11650:8;11634:14;11630:29;11626:48;11606:18;11602:73;11592:168;;11679:79;;:::i;:::-;11592:168;11791:18;11781:8;11777:33;11769:41;;11843:4;11830:18;11820:28;;11871:18;11863:6;11860:30;11857:117;;;11893:79;;:::i;:::-;11857:117;12001:2;11995:4;11991:13;11983:21;;12058:4;12050:6;12046:17;12030:14;12026:38;12020:4;12016:49;12013:136;;;12068:79;;:::i;:::-;12013:136;11522:634;11431:725;;;;;:::o;12162:129::-;12196:6;12223:20;;:::i;:::-;12213:30;;12252:33;12280:4;12272:6;12252:33;:::i;:::-;12162:129;;;:::o;12297:75::-;12330:6;12363:2;12357:9;12347:19;;12297:75;:::o;12378:169::-;12462:11;12496:6;12491:3;12484:19;12536:4;12531:3;12527:14;12512:29;;12378:169;;;;:::o;12553:122::-;12605:5;12630:39;12665:2;12660:3;12656:12;12651:3;12630:39;:::i;:::-;12621:48;;12553:122;;;;:::o;12681:118::-;12731:5;12756:37;12789:2;12784:3;12780:12;12775:3;12756:37;:::i;:::-;12747:46;;12681:118;;;;:::o;12805:96::-;12842:7;12871:24;12889:5;12871:24;:::i;:::-;12860:35;;12805:96;;;:::o;12907:77::-;12944:7;12973:5;12962:16;;12907:77;;;:::o;12990:126::-;13027:7;13067:42;13060:5;13056:54;13045:65;;12990:126;;;:::o;13122:77::-;13159:7;13188:5;13177:16;;13122:77;;;:::o;13205:86::-;13240:7;13280:4;13273:5;13269:16;13258:27;;13205:86;;;:::o;13297:154::-;13381:6;13376:3;13371;13358:30;13443:1;13434:6;13429:3;13425:16;13418:27;13297:154;;;:::o;13457:281::-;13540:27;13562:4;13540:27;:::i;:::-;13532:6;13528:40;13670:6;13658:10;13655:22;13634:18;13622:10;13619:34;13616:62;13613:88;;;13681:18;;:::i;:::-;13613:88;13721:10;13717:2;13710:22;13500:238;13457:281;;:::o;13744:180::-;13792:77;13789:1;13782:88;13889:4;13886:1;13879:15;13913:4;13910:1;13903:15;13930:117;14039:1;14036;14029:12;14053:117;14162:1;14159;14152:12;14176:117;14285:1;14282;14275:12;14299:117;14408:1;14405;14398:12;14422:117;14531:1;14528;14521:12;14545:117;14654:1;14651;14644:12;14791:117;14900:1;14897;14890:12;14914:117;15023:1;15020;15013:12;15037:117;15146:1;15143;15136:12;15160:117;15269:1;15266;15259:12;15283:102;15324:6;15375:2;15371:7;15366:2;15359:5;15355:14;15351:28;15341:38;;15283:102;;;:::o;15391:122::-;15464:24;15482:5;15464:24;:::i;:::-;15457:5;15454:35;15444:63;;15503:1;15500;15493:12;15444:63;15391:122;:::o;15519:::-;15592:24;15610:5;15592:24;:::i;:::-;15585:5;15582:35;15572:63;;15631:1;15628;15621:12;15572:63;15519:122;:::o;15647:110::-;15731:1;15724:5;15721:12;15711:40;;15747:1;15744;15737:12;15711:40;15647:110;:::o;15763:122::-;15836:24;15854:5;15836:24;:::i;:::-;15829:5;15826:35;15816:63;;15875:1;15872;15865:12;15816:63;15763:122;:::o;15891:118::-;15962:22;15978:5;15962:22;:::i;:::-;15955:5;15952:33;15942:61;;15999:1;15996;15989:12;15942:61;15891:118;:::o
Swarm Source
ipfs://f94e5a289f24dcb719c7653973fc4231d015fbb1f84da8cfdec170908e06dfd4
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in GLMR
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.