Compare commits
3 Commits
dev
...
codespaces
Author | SHA1 | Date | |
---|---|---|---|
|
31139b0236 | ||
|
9e671662a8 | ||
|
5cc60954a8 |
@ -1,2 +0,0 @@
|
||||
extends:
|
||||
- "@commitlint/config-conventional"
|
32
.devcontainer/devcontainer.json
Normal file
32
.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "Node.js",
|
||||
"image": "mcr.microsoft.com/devcontainers/javascript-node:16-bullseye",
|
||||
|
||||
// Features to add to the dev container. More info: https://containers.dev/implementors/features.
|
||||
// "features": {},
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
"postCreateCommand": "npm install",
|
||||
|
||||
// Configure tool-specific properties.
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"settings": {
|
||||
"extensions.ignoreRecommendations": true
|
||||
},
|
||||
"extensions": [
|
||||
"NomicFoundation.hardhat-solidity",
|
||||
"tintinweb.vscode-inline-bookmarks",
|
||||
"tintinweb.solidity-visual-auditor",
|
||||
"tintinweb.solidity-metrics",
|
||||
"tintinweb.graphviz-interactive-preview"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||
// "remoteUser": "root"
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
# EditorConfig http://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# All files
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.sol]
|
||||
indent_size = 4
|
12
.env.example
12
.env.example
@ -1,12 +0,0 @@
|
||||
MNEMONIC="{INSERT_12_WORD_MNEMONIC}"
|
||||
|
||||
INFURA_API_KEY="{INSERT_API_KEY}"
|
||||
ALCHEMY_API_KEY="{INSERT_API_KEY}"
|
||||
|
||||
# Block explorer API keys
|
||||
ETHERSCAN_API_KEY="{INSERT_API_KEY}"
|
||||
POLYGONSCAN_API_KEY="{INSERT_API_KEY}"
|
||||
GASPRICE_API_ENDPOINT="https://api.etherscan.io/api?module=proxy&action=eth_gasPrice"
|
||||
COINMARKETCAP_API_KEY="{INSERT_API_KEY}"
|
||||
|
||||
REPORT_GAS="true"
|
@ -1,21 +0,0 @@
|
||||
# directories
|
||||
.yarn/
|
||||
**/.coverage_artifacts
|
||||
**/.coverage_cache
|
||||
**/.coverage_contracts
|
||||
**/artifacts
|
||||
**/build
|
||||
**/cache
|
||||
**/coverage
|
||||
**/dist
|
||||
**/node_modules
|
||||
**/types
|
||||
|
||||
# files
|
||||
*.env
|
||||
*.log
|
||||
.pnp.*
|
||||
coverage.json
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
@ -1,21 +0,0 @@
|
||||
extends:
|
||||
- "eslint:recommended"
|
||||
- "plugin:@typescript-eslint/eslint-recommended"
|
||||
- "plugin:@typescript-eslint/recommended"
|
||||
- "prettier"
|
||||
parser: "@typescript-eslint/parser"
|
||||
parserOptions:
|
||||
project: "./tsconfig.json"
|
||||
plugins:
|
||||
- "@typescript-eslint"
|
||||
root: true
|
||||
rules:
|
||||
"@typescript-eslint/no-floating-promises":
|
||||
- error
|
||||
- ignoreIIFE: true
|
||||
ignoreVoid: true
|
||||
"@typescript-eslint/no-inferrable-types": "off"
|
||||
"@typescript-eslint/no-unused-vars":
|
||||
- error
|
||||
- argsIgnorePattern: "_"
|
||||
varsIgnorePattern: "_"
|
37
.gitignore
vendored
37
.gitignore
vendored
@ -1,30 +1,9 @@
|
||||
# directories
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/releases
|
||||
!.yarn/plugins
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
artifacts
|
||||
**/artifacts
|
||||
artifacts/build-info
|
||||
**/build
|
||||
**/ref
|
||||
**/cache
|
||||
**/coverage
|
||||
**/.coverage_artifacts
|
||||
**/.coverage_cache
|
||||
**/.coverage_contracts
|
||||
**/dist
|
||||
**/node_modules
|
||||
.deps
|
||||
src/types
|
||||
|
||||
# files
|
||||
*.env
|
||||
*.log
|
||||
.pnp.*
|
||||
node_modules
|
||||
.env
|
||||
coverage
|
||||
coverage.json
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
#Hardhat files
|
||||
cache
|
||||
artifacts/build-info
|
||||
artifacts/@openzeppelin
|
1
.husky/.gitignore
vendored
1
.husky/.gitignore
vendored
@ -1 +0,0 @@
|
||||
_
|
@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
yarn dlx commitlint --edit $1
|
@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
yarn dlx lint-staged
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"*.{js,json,md,sol,ts,yaml,yml}": [
|
||||
"prettier --config ./.prettierrc.yaml --write"
|
||||
]
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
# directories
|
||||
.yarn/
|
||||
**/.coverage_artifacts
|
||||
**/.coverage_cache
|
||||
**/.coverage_contracts
|
||||
**/artifacts
|
||||
**/build
|
||||
**/cache
|
||||
**/coverage
|
||||
**/dist
|
||||
**/node_modules
|
||||
**/types
|
||||
|
||||
# files
|
||||
*.env
|
||||
*.log
|
||||
.pnp.*
|
||||
coverage.json
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
contracts/p2pix.sol
|
@ -1,16 +0,0 @@
|
||||
arrowParens: avoid
|
||||
bracketSpacing: true
|
||||
endOfLine: auto
|
||||
importOrder: ["<THIRD_PARTY_MODULES>", "^[./]"]
|
||||
importOrderParserPlugins: ["typescript"]
|
||||
importOrderSeparation: true
|
||||
importOrderSortSpecifiers: true
|
||||
printWidth: 62
|
||||
singleQuote: false
|
||||
tabWidth: 2
|
||||
trailingComma: all
|
||||
|
||||
overrides:
|
||||
- files: "*.sol"
|
||||
options:
|
||||
tabWidth: 4
|
18
.solcover.js
18
.solcover.js
@ -1,18 +0,0 @@
|
||||
module.exports = {
|
||||
configureYulOptimizer: true,
|
||||
solcOptimizerDetails: {
|
||||
deduplicate: true,
|
||||
cse: true,
|
||||
constantOptimizer: true,
|
||||
peephole: true,
|
||||
jumpdestRemover: true,
|
||||
yul: true,
|
||||
// inliner: false,
|
||||
// orderLiterals: true,
|
||||
},
|
||||
istanbulReporter: ["html", "lcov"],
|
||||
providerOptions: {
|
||||
mnemonic: process.env.MNEMONIC,
|
||||
},
|
||||
skipFiles: ["test", 'core/BaseUtils.sol', 'core/OwnerSettings.sol'],
|
||||
};
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"extends": "solhint:recommended",
|
||||
"plugins": ["prettier"],
|
||||
"rules": {
|
||||
"code-complexity": ["error", 8],
|
||||
"compiler-version": ["error", ">=0.8.4"],
|
||||
"const-name-snakecase": "off",
|
||||
"constructor-syntax": "error",
|
||||
"func-visibility": [
|
||||
"error",
|
||||
{ "ignoreConstructors": true }
|
||||
],
|
||||
"max-line-length": ["error", 120],
|
||||
"not-rely-on-time": "off",
|
||||
"prettier/prettier": [
|
||||
"error",
|
||||
{
|
||||
"endOfLine": "auto"
|
||||
}
|
||||
],
|
||||
"reason-string": ["warn", { "maxLength": 64 }]
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
# directories
|
||||
**/artifacts
|
||||
**/node_modules
|
546
.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
vendored
546
.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
vendored
File diff suppressed because one or more lines are too long
786
.yarn/releases/yarn-3.2.1.cjs
vendored
786
.yarn/releases/yarn-3.2.1.cjs
vendored
File diff suppressed because one or more lines are too long
@ -1,7 +0,0 @@
|
||||
nodeLinker: node-modules
|
||||
|
||||
plugins:
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
|
||||
spec: "@yarnpkg/plugin-interactive-tools"
|
||||
|
||||
yarnPath: .yarn/releases/yarn-3.2.1.cjs
|
174
README.md
174
README.md
@ -1,160 +1,68 @@
|
||||
# p2pix-smart-contracts
|
||||
|
||||
**Repository for P2Pix EVM contracts to be imported by the project.**
|
||||
Repository for P2Pix EVM contracts to be imported by the project.
|
||||
|
||||
## SM Dependency Tree
|
||||
## Installation
|
||||
|
||||
Import the repository on your app to allow use the artifacts for Ethers.
|
||||
|
||||
```rs
|
||||
./contracts/
|
||||
├── Constants.sol
|
||||
├── DataTypes.sol
|
||||
├── EventAndErrors.sol
|
||||
├── lib
|
||||
│ ├── auth
|
||||
│ │ └── Owned.sol
|
||||
│ ├── interfaces
|
||||
│ │ └── IReputation.sol
|
||||
│ ├── mock
|
||||
│ │ └── mockToken.sol
|
||||
│ ├── tokens
|
||||
│ │ └── ERC20.sol
|
||||
│ └── utils
|
||||
│ ├── ECDSA.sol
|
||||
│ ├── MerkleProofLib.sol
|
||||
│ ├── Multicall.sol
|
||||
│ ├── ReentrancyGuard.sol
|
||||
│ └── SafeTransferLib.sol
|
||||
├── p2pix.sol
|
||||
└── Reputation.sol
|
||||
```
|
||||
|
||||
## Callgraph
|
||||
|
||||

|
||||
|
||||
## Current Deployment addresses
|
||||
|
||||
### V1
|
||||
|
||||
| Testnet | Token Address | P2pix Address |
|
||||
| ------- | ------------------------------------------ | ------------------------------------------ |
|
||||
| Goerli | 0x294003F602c321627152c6b7DED3EAb5bEa853Ee | 0x5f3EFA9A90532914545CEf527C530658af87e196 |
|
||||
| Mumbai | 0x294003F602c321627152c6b7DED3EAb5bEa853Ee | 0x5f3EFA9A90532914545CEf527C530658af87e196 |
|
||||
|
||||
<!-- All contracts deployed by 0x8dC06F985C131166570825F52447E8c88d64aE20 -->
|
||||
|
||||
<!-- https://goerli.etherscan.io/address/0x294003F602c321627152c6b7DED3EAb5bEa853Ee#code -->
|
||||
|
||||
<!-- https://goerli.etherscan.io/address/0x5f3EFA9A90532914545CEf527C530658af87e196#code -->
|
||||
|
||||
<!-- https://mumbai.polygonscan.com/address/0x294003F602c321627152c6b7DED3EAb5bEa853Ee#code -->
|
||||
|
||||
<!-- https://mumbai.polygonscan.com/address/0x5f3EFA9A90532914545CEf527C530658af87e196#code -->
|
||||
|
||||
### V2
|
||||
|
||||
| Testnet | Token Address | P2pix Address | Reputation Address | Multicall Address |
|
||||
| ------- | ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | ------------------------------------------ |
|
||||
| Goerli | 0x4A2886EAEc931e04297ed336Cc55c4eb7C75BA00 | 0x2414817FF64A114d91eCFA16a834d3fCf69103d4 | 0x2CFD9354Ec7614fEf036EFd6A730dA1d5fC2762A | 0x8FE009992d96A86c7f0Bccdaf1eC3471E302a8a6 |
|
||||
| Mumbai | 0xC86042E9F2977C62Da8c9dDF7F9c40fde4796A29 | 0x4A2886EAEc931e04297ed336Cc55c4eb7C75BA00 | 0x570445E3eF413bCDb5De79ed27B1c3840683e385 | 0x718B2C4DE4F9654E1349F610ff561249bfe1c418 |
|
||||
|
||||
<!-- All contracts deployed by 0x8dC06F985C131166570825F52447E8c88d64aE20 -->
|
||||
<!-- https://goerli.etherscan.io/address/0x4A2886EAEc931e04297ed336Cc55c4eb7C75BA00#code -->
|
||||
<!-- https://goerli.etherscan.io/address/0x2414817FF64A114d91eCFA16a834d3fCf69103d4#code -->
|
||||
<!-- https://goerli.etherscan.io/address/0x2CFD9354Ec7614fEf036EFd6A730dA1d5fC2762A#code -->
|
||||
<!-- https://goerli.etherscan.io/address/0x8FE009992d96A86c7f0Bccdaf1eC3471E302a8a6#code -->
|
||||
|
||||
<!-- https://mumbai.polygonscan.com/address/0xC86042E9F2977C62Da8c9dDF7F9c40fde4796A29#code -->
|
||||
<!-- https://mumbai.polygonscan.com/address/0x4A2886EAEc931e04297ed336Cc55c4eb7C75BA00#code -->
|
||||
<!-- https://mumbai.polygonscan.com/address/0x570445e3ef413bcdb5de79ed27b1c3840683e385#code -->
|
||||
<!-- https://mumbai.polygonscan.com/address/0x718B2C4DE4F9654E1349F610ff561249bfe1c418#code -->
|
||||
|
||||
## Usage
|
||||
|
||||
### Pre Requisites
|
||||
|
||||
Before installing, create a `.env` file and set a BIP-39 compatible mnemonic and other env criteria as in `.env.example`.
|
||||
|
||||
### Install
|
||||
|
||||
```sh
|
||||
$ yarn install
|
||||
npm install --save git+https://github.com/doiim/p2pix-smart-contracts.git
|
||||
```
|
||||
|
||||
### Compile
|
||||
|
||||
```sh
|
||||
$ yarn compile
|
||||
```
|
||||
|
||||
**_NOTE:_** TypeChain artifacts generated at compile time.
|
||||
|
||||
### Test
|
||||
|
||||
```sh
|
||||
$ yarn test
|
||||
```
|
||||
|
||||
### Report Gas
|
||||
|
||||
```sh
|
||||
$ REPORT_GAS=true yarn test
|
||||
```
|
||||
|
||||
**_NOTE_:** Gas usage per unit test and average gas per method call.
|
||||
|
||||
### Clean
|
||||
|
||||
Delete the smart contract artifacts and cache:
|
||||
|
||||
```sh
|
||||
$ yarn clean
|
||||
```
|
||||
|
||||
## Importing artifacts
|
||||
|
||||
To import artifacts on the project use the following:
|
||||
|
||||
```ts
|
||||
import P2PIXArtifact from "p2pix-smart-contracts/artifacts/contracts/p2pix.sol/P2PIX.json";
|
||||
```
|
||||
import P2PIXArtifact from 'p2pix-smart-contracts/artifacts/contracts/p2pix.sol/P2PIX.json'
|
||||
```
|
||||
|
||||
To grab deployment addresses you can just grab from deploys folder:
|
||||
|
||||
```ts
|
||||
import localhostDeploys from "p2pix-smart-contracts/deploys/localhost.json";
|
||||
```
|
||||
import localhostDeploys from 'p2pix-smart-contracts/deploys/localhost.json'
|
||||
```
|
||||
|
||||
## Deploying to local environment
|
||||
The default deploy addresses for localhost is the following:
|
||||
| Contract | Address |
|
||||
|-|-|
|
||||
|p2pix|`0x5FbDB2315678afecb367f032d93F642f64180aa3`|
|
||||
|token|`0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512`|
|
||||
|
||||
On the first teminal, use the following command and import some wallets to your Metamask, then connect to the network pointed:
|
||||
Then use a Contract instance to interact directly with it:
|
||||
|
||||
```sh
|
||||
yarn hardhat node
|
||||
```
|
||||
const p2pixContract = new ethers.Contract(address, P2PIXArtifact.abi, signer);
|
||||
```
|
||||
|
||||
On the second teminal, run the following commands:
|
||||
## Deploying local environment
|
||||
|
||||
```sh
|
||||
yarn deploy1:localhost
|
||||
yarn deploy2:localhost
|
||||
Clone the repo and install dependencies:
|
||||
```
|
||||
git clone https://github.com/doiim/p2pix-smart-contracts.git
|
||||
cd p2pix-smart-contract
|
||||
npm install
|
||||
```
|
||||
|
||||
**_NOTE_:** The second script transfers 2M tokens to the first wallet of the node.
|
||||
On the first teminal use the following command and import some wallets to your Metamask and connect to the network pointed:
|
||||
```
|
||||
npx hardhat node
|
||||
```
|
||||
|
||||
On the second teminal run following commands:
|
||||
```
|
||||
npx hardhat run --network localhost scripts/1-deploy-p2pix.js
|
||||
npx hardhat run --network localhost scripts/2-deploy-mockToken.js
|
||||
```
|
||||
|
||||
The second script transfer 2M tokens to the firrs wallet of the node.
|
||||
To use the P2Pix smart contract first transfer some of the tokens to other wallets.
|
||||
|
||||
## Deploying to testnets
|
||||
## Testing
|
||||
|
||||
Deploy to Ethereum's Goerli testnet:
|
||||
To run tests, clone this repo, install dependencies and run Hardhat tests.
|
||||
|
||||
```sh
|
||||
yarn deploy1:goerli
|
||||
yarn deploy2:goerli
|
||||
```
|
||||
|
||||
Deploy to Polygon's Mumbai testnet:
|
||||
|
||||
```sh
|
||||
yarn deploy1:mumbai
|
||||
yarn deploy2:mumbai
|
||||
git clone https://github.com/doiim/p2pix-smart-contracts.git
|
||||
cd p2pix-smart-contract
|
||||
npm install
|
||||
npx hardhat test
|
||||
```
|
||||
|
4
artifacts/contracts/mockToken.sol/MockToken.dbg.json
Normal file
4
artifacts/contracts/mockToken.sol/MockToken.dbg.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"_format": "hh-sol-dbg-1",
|
||||
"buildInfo": "../../build-info/5f0db55f399477fd77a196dfab69a373.json"
|
||||
}
|
292
artifacts/contracts/mockToken.sol/MockToken.json
Normal file
292
artifacts/contracts/mockToken.sol/MockToken.json
Normal file
File diff suppressed because one or more lines are too long
4
artifacts/contracts/p2pix.sol/P2PIX.dbg.json
Normal file
4
artifacts/contracts/p2pix.sol/P2PIX.dbg.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"_format": "hh-sol-dbg-1",
|
||||
"buildInfo": "../../build-info/fa666dddb19de15d02d4eaf695a7b974.json"
|
||||
}
|
437
artifacts/contracts/p2pix.sol/P2PIX.json
Normal file
437
artifacts/contracts/p2pix.sol/P2PIX.json
Normal file
File diff suppressed because one or more lines are too long
@ -1,79 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.19;
|
||||
|
||||
import { IReputation } from "./lib/interfaces/IReputation.sol";
|
||||
|
||||
contract Reputation is IReputation {
|
||||
/// @dev Asymptote numerator constant value for the `limiter` fx.
|
||||
uint256 public constant maxLimit = 1e6;
|
||||
/// @dev Denominator's constant operand for the `limiter` fx.
|
||||
uint256 public constant magicValue = 2.5e11;
|
||||
|
||||
// prettier-ignore
|
||||
// solhint-disable no-inline-assembly
|
||||
// solhint-disable-next-line no-empty-blocks
|
||||
constructor(/* */) payable {/* */}
|
||||
|
||||
function limiter(
|
||||
uint256 _userCredit
|
||||
)
|
||||
external
|
||||
pure
|
||||
override(IReputation)
|
||||
returns (uint256 _spendLimit)
|
||||
{
|
||||
_spendLimit = (1 +
|
||||
((maxLimit * _userCredit) /
|
||||
sqrt(
|
||||
magicValue + (_userCredit * _userCredit)
|
||||
)));
|
||||
}
|
||||
|
||||
/// @notice Taken from Solmate's FixedPointMathLib.
|
||||
/// (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
|
||||
function sqrt(
|
||||
uint256 x
|
||||
) internal pure returns (uint256 z) {
|
||||
/// @solidity memory-safe-assembly
|
||||
assembly {
|
||||
let y := x // We start y at x, which will help us make our initial estimate.
|
||||
|
||||
z := 181 // The "correct" value is 1, but this saves a multiplication later.
|
||||
|
||||
// We check y >= 2^(k + 8) but shift right by k bits
|
||||
// each branch to ensure that if x >= 256, then y >= 256.
|
||||
if iszero(
|
||||
lt(y, 0x10000000000000000000000000000000000)
|
||||
) {
|
||||
y := shr(128, y)
|
||||
z := shl(64, z)
|
||||
}
|
||||
if iszero(lt(y, 0x1000000000000000000)) {
|
||||
y := shr(64, y)
|
||||
z := shl(32, z)
|
||||
}
|
||||
if iszero(lt(y, 0x10000000000)) {
|
||||
y := shr(32, y)
|
||||
z := shl(16, z)
|
||||
}
|
||||
if iszero(lt(y, 0x1000000)) {
|
||||
y := shr(16, y)
|
||||
z := shl(8, z)
|
||||
}
|
||||
|
||||
// There is no overflow risk here since y < 2^136 after the first branch above.
|
||||
z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.
|
||||
|
||||
// Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.
|
||||
z := shr(1, add(z, div(x, z)))
|
||||
z := shr(1, add(z, div(x, z)))
|
||||
z := shr(1, add(z, div(x, z)))
|
||||
z := shr(1, add(z, div(x, z)))
|
||||
z := shr(1, add(z, div(x, z)))
|
||||
z := shr(1, add(z, div(x, z)))
|
||||
z := shr(1, add(z, div(x, z)))
|
||||
|
||||
z := sub(z, lt(div(x, z), z))
|
||||
}
|
||||
}
|
||||
}
|
@ -1,181 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.19;
|
||||
|
||||
import { ERC20, OwnerSettings } from "contracts/core/OwnerSettings.sol";
|
||||
|
||||
import { ECDSA } from "contracts/lib/utils/ECDSA.sol";
|
||||
import { MerkleProofLib as Merkle } from "contracts/lib/utils/MerkleProofLib.sol";
|
||||
import { ReentrancyGuard } from "contracts/lib/utils/ReentrancyGuard.sol";
|
||||
|
||||
abstract contract BaseUtils is
|
||||
OwnerSettings,
|
||||
ReentrancyGuard
|
||||
{
|
||||
/// ███ Storage ████████████████████████████████████████████████████████████
|
||||
|
||||
/// @dev List of Pix transactions already signed.
|
||||
/// mapping(bytes32 => bool) public usedTransactions;
|
||||
/// @dev Value in custom storage slot given by:
|
||||
/// let value := sload(bytes32).
|
||||
|
||||
/// ███ Helper FX ██████████████████████████████████████████████████████████
|
||||
function _setUsedTransactions(bytes32 message) internal {
|
||||
assembly ("memory-safe") {
|
||||
sstore(message, true)
|
||||
}
|
||||
}
|
||||
|
||||
function usedTransactions(
|
||||
bytes32 message
|
||||
) public view returns (bool used) {
|
||||
assembly ("memory-safe") {
|
||||
used := sload(message)
|
||||
}
|
||||
}
|
||||
|
||||
function _signerCheck(
|
||||
bytes32 _message,
|
||||
bytes calldata _signature
|
||||
) internal view {
|
||||
if (usedTransactions(_message))
|
||||
revert TxAlreadyUsed();
|
||||
|
||||
if (
|
||||
!validBacenSigners(
|
||||
_castAddrToKey(
|
||||
ECDSA.recoverCalldata(
|
||||
ECDSA.toEthSignedMessageHash(
|
||||
_message
|
||||
),
|
||||
_signature
|
||||
)
|
||||
)
|
||||
)
|
||||
) revert InvalidSigner();
|
||||
}
|
||||
|
||||
function _merkleVerify(
|
||||
bytes32[] calldata _merkleProof,
|
||||
bytes32 _root,
|
||||
address _addr
|
||||
) internal pure {
|
||||
if (
|
||||
!Merkle.verify(
|
||||
_merkleProof,
|
||||
_root,
|
||||
bytes32(uint256(uint160(_addr)))
|
||||
)
|
||||
) revert AddressDenied();
|
||||
}
|
||||
|
||||
function _castBool(
|
||||
bool _valid
|
||||
) internal pure returns (uint256 _validCasted) {
|
||||
assembly ("memory-safe") {
|
||||
_validCasted := _valid
|
||||
}
|
||||
}
|
||||
|
||||
function getStr(
|
||||
string memory str
|
||||
) public pure returns (bytes32 strEnc) {
|
||||
bytes memory enc = bytes(abi.encodePacked(str));
|
||||
assembly ("memory-safe") {
|
||||
if lt(0x20, mload(enc)) {
|
||||
invalid()
|
||||
}
|
||||
strEnc := mload(add(enc, 0x20))
|
||||
}
|
||||
}
|
||||
|
||||
function _setSellerBalance(
|
||||
address _sellerKey,
|
||||
ERC20 _erc20,
|
||||
uint256 _packed,
|
||||
bytes32 _pixTarget
|
||||
) internal {
|
||||
assembly ("memory-safe") {
|
||||
mstore(0x20, _erc20)
|
||||
mstore(0x0c, _SELLER_BALANCE_SLOT_SEED)
|
||||
mstore(0x00, _sellerKey)
|
||||
let _loc := keccak256(0x0c, 0x34)
|
||||
sstore(add(_loc, 0x01), _packed)
|
||||
sstore(_loc, _pixTarget)
|
||||
}
|
||||
}
|
||||
|
||||
function _setValidState(
|
||||
address _sellerKey,
|
||||
ERC20 _erc20,
|
||||
uint256 _packed
|
||||
) internal {
|
||||
assembly ("memory-safe") {
|
||||
mstore(0x20, _erc20)
|
||||
mstore(0x0c, _SELLER_BALANCE_SLOT_SEED)
|
||||
mstore(0x00, _sellerKey)
|
||||
let _loc := keccak256(0x0c, 0x34)
|
||||
sstore(add(_loc, 0x01), _packed)
|
||||
}
|
||||
}
|
||||
|
||||
function _addSellerBalance(
|
||||
address _sellerKey,
|
||||
ERC20 _erc20,
|
||||
uint256 _amount
|
||||
) internal {
|
||||
assembly ("memory-safe") {
|
||||
mstore(0x20, _erc20)
|
||||
mstore(0x0c, _SELLER_BALANCE_SLOT_SEED)
|
||||
mstore(0x00, _sellerKey)
|
||||
let _loc := add(keccak256(0x0c, 0x34), 0x01)
|
||||
sstore(_loc, add(sload(_loc), _amount))
|
||||
}
|
||||
}
|
||||
|
||||
function _decSellerBalance(
|
||||
address _sellerKey,
|
||||
ERC20 _erc20,
|
||||
uint256 _amount
|
||||
) internal {
|
||||
assembly ("memory-safe") {
|
||||
mstore(0x20, _erc20)
|
||||
mstore(0x0c, _SELLER_BALANCE_SLOT_SEED)
|
||||
mstore(0x00, _sellerKey)
|
||||
let _loc := add(keccak256(0x0c, 0x34), 0x01)
|
||||
sstore(_loc, sub(sload(_loc), _amount))
|
||||
}
|
||||
}
|
||||
|
||||
function __sellerBalance(
|
||||
address _sellerKey,
|
||||
ERC20 _erc20
|
||||
) internal view returns (uint256 _packed) {
|
||||
assembly ("memory-safe") {
|
||||
mstore(0x20, _erc20)
|
||||
mstore(0x0c, _SELLER_BALANCE_SLOT_SEED)
|
||||
mstore(0x00, _sellerKey)
|
||||
_packed := sload(add(keccak256(0x0c, 0x34), 0x01))
|
||||
}
|
||||
}
|
||||
|
||||
/// @notice Public method that handles `address`
|
||||
/// to `uint256` safe type casting.
|
||||
/// @dev Function sighash: 0x4b2ae980.
|
||||
function _castAddrToKey(
|
||||
address _addr
|
||||
) public pure returns (uint256 _key) {
|
||||
// _key = uint256(uint160(address(_addr))) << 12;
|
||||
assembly ("memory-safe") {
|
||||
_key := shl(0xc, _addr)
|
||||
}
|
||||
}
|
||||
|
||||
function _castKeyToAddr(
|
||||
uint256 _key
|
||||
) public pure returns (address _addr) {
|
||||
// _addr = address(uint160(uint256(_key >> 12)));
|
||||
assembly ("memory-safe") {
|
||||
_addr := shr(0xc, _key)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.19;
|
||||
|
||||
abstract contract Constants {
|
||||
/// ███ Constants ██████████████████████████████████████████████████████████
|
||||
|
||||
uint256 constant _ROOT_UPDATED_EVENT_SIGNATURE =
|
||||
0x0b294da292f26e55fd442b5c0164fbb9013036ff00c5cfdde0efd01c1baaf632;
|
||||
uint256 constant _ALLOWED_ERC20_UPDATED_EVENT_SIGNATURE =
|
||||
0x5d6e86e5341d57a92c49934296c51542a25015c9b1782a1c2722a940131c3d9a;
|
||||
uint256 constant _TRUSTED_FORWARDER_UPDATED_EVENT_SIGNATURE =
|
||||
0xbee55516e29d3969d3cb8eb01351eb3c52d06f9e2435bd5a8bfe3647e185df92;
|
||||
|
||||
/// @dev Seller casted to key => Seller's allowlist merkleroot.
|
||||
/// mapping(uint256 => bytes32) public sellerAllowList;
|
||||
uint256 constant _SELLER_ALLOWLIST_SLOT_SEED = 0x74dfee70;
|
||||
/// @dev Tokens allowed to serve as the underlying amount of a deposit.
|
||||
/// mapping(ERC20 => bool) public allowedERC20s;
|
||||
uint256 constant _ALLOWED_ERC20_SLOT_SEED = 0xcbc9d1c4;
|
||||
|
||||
/// @dev `balance` max. value = 10**26.
|
||||
/// @dev `pixTarget` keys are restricted to 160 bits.
|
||||
/// mapping(uint256 => mapping(ERC20 => { `uint256`, `uint96` } )) public sellerBalance;
|
||||
|
||||
/// @dev Bits layout:
|
||||
/// `bytes32` [0...255] := pixTarget
|
||||
/// `uint96` [0...94] := balance
|
||||
/// `bool` [95] := valid
|
||||
|
||||
/// @dev Value in custom storage slot given by:
|
||||
/// mstore(0x20, token)
|
||||
/// mstore(0x0c, _SELLER_BALANCE_SLOT_SEED)
|
||||
/// mstore(0x00, seller)
|
||||
/// let value := sload(keccak256(0x0c, 0x34)).
|
||||
uint256 constant _SELLER_BALANCE_SLOT_SEED = 0x739094b1;
|
||||
|
||||
/// @dev The bitmask of `sellerBalance` entry.
|
||||
uint256 constant BITMASK_SB_ENTRY = (1 << 94) - 1;
|
||||
/// @dev The bit position of `valid` in `sellerBalance`.
|
||||
uint256 constant BITPOS_VALID = 95;
|
||||
|
||||
/// @dev The scalar of BRZ token.
|
||||
uint256 constant WAD = 1e18;
|
||||
uint256 constant MAXBALANCE_UPPERBOUND = 1e8 ether;
|
||||
uint256 constant REPUTATION_LOWERBOUND = 1e2 ether;
|
||||
uint256 constant LOCKAMOUNT_UPPERBOUND = 1e6 ether;
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.19;
|
||||
|
||||
import { ERC20 } from "contracts/lib/tokens/ERC20.sol";
|
||||
|
||||
library DataTypes {
|
||||
|
||||
struct Lock {
|
||||
uint256 counter;
|
||||
uint256 expirationBlock;
|
||||
bytes32 pixTarget;
|
||||
uint80 amount;
|
||||
ERC20 token;
|
||||
address buyerAddress;
|
||||
address seller;
|
||||
}
|
||||
|
||||
// prettier-ignore
|
||||
enum LockStatus {
|
||||
Inexistent, // 0 := Uninitialized Lock.
|
||||
Active, // 1 := Valid Lock.
|
||||
Expired, // 2 := Expired Lock.
|
||||
Released // 3 := Already released Lock.
|
||||
}
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.19;
|
||||
|
||||
import { ERC20 } from "contracts/lib/tokens/ERC20.sol";
|
||||
|
||||
// prettier-ignore
|
||||
interface EventAndErrors {
|
||||
/// ███ Events ████████████████████████████████████████████████████████████
|
||||
|
||||
/// @dev 0x63d8d7d5e63e9840ec91a12a160d27b7cfab294f6ba070b7359692acfe6b03bf
|
||||
event DepositAdded(
|
||||
address indexed seller,
|
||||
// uint256 depositID,
|
||||
ERC20 token,
|
||||
uint256 amount
|
||||
);
|
||||
/// @dev 0xca585721b6b442dc9183932f7c84dc2880efb67c4da52cc06873e78971105d49
|
||||
event ValidSet(
|
||||
address indexed seller,
|
||||
ERC20 token,
|
||||
bool state
|
||||
);
|
||||
/// @dev 0x2cd6435b1b961c13f55202979edd0765a809f69a539d8a477436c94c1211e43e
|
||||
event DepositWithdrawn(
|
||||
address indexed seller,
|
||||
ERC20 token,
|
||||
uint256 amount
|
||||
);
|
||||
/// @dev 0x8fb3989f70bd172a37d15b41b015e48ea09d59329638377304a4198cd0c4ea65
|
||||
event LockAdded(
|
||||
address indexed buyer,
|
||||
uint256 indexed lockID,
|
||||
address seller,
|
||||
uint256 amount
|
||||
);
|
||||
/// @dev 0x364537f14276f2a0ce9905588413f96454cbb8fb2e4f5308389307c1098bede8
|
||||
event LockReleased(
|
||||
address indexed buyer,
|
||||
uint256 lockId,
|
||||
uint256 amount
|
||||
);
|
||||
/// @dev 0x830501e61b8b075e170b22a430e39454bdb12ed3e9620e586430b6ac00079da5
|
||||
event LockReturned(
|
||||
address indexed buyer,
|
||||
uint256 lockId
|
||||
);
|
||||
/// @dev 0xeaff4b37086828766ad3268786972c0cd24259d4c87a80f9d3963a3c3d999b0d
|
||||
event FundsWithdrawn(
|
||||
address owner,
|
||||
uint256 amount
|
||||
);
|
||||
/// @dev 0x0b294da292f26e55fd442b5c0164fbb9013036ff00c5cfdde0efd01c1baaf632
|
||||
event RootUpdated(
|
||||
address indexed seller,
|
||||
bytes32 indexed merkleRoot
|
||||
);
|
||||
/// @dev 0x5d6e86e5341d57a92c49934296c51542a25015c9b1782a1c2722a940131c3d9a
|
||||
event AllowedERC20Updated(
|
||||
address indexed token,
|
||||
bool indexed state
|
||||
);
|
||||
/// @dev 0xbee55516e29d3969d3cb8eb01351eb3c52d06f9e2435bd5a8bfe3647e185df92
|
||||
event TrustedForwarderUpdated(
|
||||
address indexed forwarder,
|
||||
bool indexed state
|
||||
);
|
||||
/// @dev 0xe127cf589a3879da0156d4a24f43b44f65cfa3570de594806b0bfa2fcf06884f
|
||||
event ReputationUpdated(address reputation);
|
||||
/// @dev 0x70fa43ca70216ad905ade86b9e650a691b2ce5a01980d0a81bdd8324141b8511
|
||||
event LockBlocksUpdated(uint256 blocks);
|
||||
/// @dev 0x14a422d2412784a5749d03da98921fe468c98577b767851389a9f58ea5a363d7
|
||||
event ValidSignersUpdated(address[] signers);
|
||||
|
||||
|
||||
/// ███ Errors ████████████████████████████████████████████████████████████
|
||||
|
||||
/// @dev Only seller could call this function.
|
||||
/// @dev `msg.sender` and the seller differ.
|
||||
/// @dev 0x85d1f726
|
||||
error OnlySeller();
|
||||
/// @dev Lock not expired or already released.
|
||||
/// @dev Another lock with same ID is not expired yet.
|
||||
/// @dev 0xd0404f85
|
||||
error NotExpired();
|
||||
/// @dev Loop bounds have overflowed.
|
||||
/// @dev 0xdfb035c9
|
||||
error LoopOverflow();
|
||||
/// @dev Deposit not valid anymore.
|
||||
/// @dev 0xb2e532de
|
||||
error InvalidDeposit();
|
||||
/// @dev Not enough token remaining on deposit.
|
||||
/// @dev 0x22bbb43c
|
||||
error NotEnoughTokens();
|
||||
/// @dev Lock already released or returned.
|
||||
/// @dev 0x63b4904e
|
||||
error AlreadyReleased();
|
||||
/// @dev Transaction already used to unlock payment.
|
||||
/// @dev 0xf490a6ea
|
||||
error TxAlreadyUsed();
|
||||
/// @dev Signer is not a valid signer.
|
||||
/// @dev 0x815e1d64
|
||||
error InvalidSigner();
|
||||
/// @dev Address doesn't exist in a MerkleTree.
|
||||
/// @dev Address not allowed as relayer.
|
||||
/// @dev 0x3b8474be
|
||||
error AddressDenied();
|
||||
/// @dev Arrays' length don't match.
|
||||
/// @dev 0xff633a38
|
||||
error LengthMismatch();
|
||||
/// @dev No tokens array provided as argument.
|
||||
/// @dev 0xdf957883
|
||||
error NoTokens();
|
||||
/// @dev Token address not allowed to be deposited.
|
||||
/// @dev 0x1578328e
|
||||
error TokenDenied();
|
||||
/// @dev Wished amount to be locked exceeds the limit allowed.
|
||||
/// @dev 0x1c18f846
|
||||
error AmountNotAllowed();
|
||||
/// @dev Reverts when success return value returns false.
|
||||
/// @dev 0xe10bf1cc
|
||||
error StaticCallFailed();
|
||||
/// @dev Reverts on an expired lock.
|
||||
/// @dev 0xf6fafba0
|
||||
error LockExpired();
|
||||
/// @dev 0xce3a3d37
|
||||
error DecOverflow();
|
||||
/// @dev 0xf3fb0eb9
|
||||
error MaxBalExceeded();
|
||||
/// @dev 0x6a3bc53e
|
||||
error EmptyPixTarget();
|
||||
/// @dev 0x87138d5c
|
||||
error NotInitialized();
|
||||
}
|
@ -1,241 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.19;
|
||||
|
||||
import { ERC2771Context as ERC2771 } from "contracts/lib/metatx/ERC2771Context.sol";
|
||||
import { ERC20, SafeTransferLib } from "contracts/lib/utils/SafeTransferLib.sol";
|
||||
import { IReputation } from "contracts/lib/interfaces/IReputation.sol";
|
||||
import { EventAndErrors } from "contracts/core/EventAndErrors.sol";
|
||||
import { Constants } from "contracts/core/Constants.sol";
|
||||
import { Owned } from "contracts/lib/auth/Owned.sol";
|
||||
|
||||
abstract contract OwnerSettings is
|
||||
Constants,
|
||||
EventAndErrors,
|
||||
Owned(msg.sender),
|
||||
ERC2771
|
||||
{
|
||||
/// ███ Storage ████████████████████████████████████████████████████████████
|
||||
|
||||
/// @dev List of valid Bacen signature addresses
|
||||
/// mapping(uint256 => bool) public validBacenSigners;
|
||||
/// @dev Value in custom storage slot given by:
|
||||
/// let value := sload(shl(12, address)).
|
||||
|
||||
IReputation public reputation;
|
||||
/// @dev Default blocks that lock will hold tokens.
|
||||
uint256 public defaultLockBlocks;
|
||||
|
||||
/// ███ Constructor ████████████████████████████████████████████████████████
|
||||
|
||||
constructor(
|
||||
uint256 defaultBlocks,
|
||||
address[] memory validSigners,
|
||||
address _reputation,
|
||||
ERC20[] memory tokens,
|
||||
bool[] memory tokenStates
|
||||
) {
|
||||
setDefaultLockBlocks(defaultBlocks);
|
||||
setValidSigners(validSigners);
|
||||
setReputation(IReputation(_reputation));
|
||||
tokenSettings(tokens, tokenStates);
|
||||
}
|
||||
|
||||
/// ███ Owner Only █████████████████████████████████████████████████████████
|
||||
|
||||
function setTrustedFowarders(
|
||||
address[] memory forwarders,
|
||||
bool[] memory states
|
||||
) external onlyOwner {
|
||||
assembly ("memory-safe") {
|
||||
// first 32 bytes eq to array's length
|
||||
let fLen := mload(forwarders)
|
||||
// halts execution if forwarders.length eq 0
|
||||
if iszero(fLen) {
|
||||
invalid()
|
||||
}
|
||||
// revert with `LengthMismatch()`
|
||||
if iszero(eq(fLen, mload(states))) {
|
||||
mstore(0x00, 0xff633a38)
|
||||
revert(0x1c, 0x04)
|
||||
}
|
||||
let fLoc := add(forwarders, 0x20)
|
||||
let sLoc := add(states, 0x20)
|
||||
for {
|
||||
let end := add(fLoc, shl(5, fLen))
|
||||
} iszero(eq(fLoc, end)) {
|
||||
fLoc := add(fLoc, 0x20)
|
||||
sLoc := add(sLoc, 0x20)
|
||||
} {
|
||||
// cache hashmap entry in scratch space
|
||||
mstore(0x20, trustedForwarders.slot)
|
||||
mstore(0x00, mload(fLoc))
|
||||
// let mapSlot := keccak256(0x00, 0x40)
|
||||
sstore(keccak256(0x00, 0x40), mload(sLoc))
|
||||
|
||||
// emit TrustedForwarderUpdated(address, bool)
|
||||
log3(
|
||||
0,
|
||||
0,
|
||||
_TRUSTED_FORWARDER_UPDATED_EVENT_SIGNATURE,
|
||||
mload(fLoc),
|
||||
mload(sLoc)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Contract's underlying balance withdraw method.
|
||||
/// @dev Function sighash: 0x5fd8c710.
|
||||
function withdrawBalance() external onlyOwner {
|
||||
uint256 balance = address(this).balance;
|
||||
SafeTransferLib.safeTransferETH(msg.sender, balance);
|
||||
emit FundsWithdrawn(msg.sender, balance);
|
||||
}
|
||||
|
||||
function setReputation(
|
||||
IReputation _reputation
|
||||
) public onlyOwner {
|
||||
assembly ("memory-safe") {
|
||||
sstore(reputation.slot, _reputation)
|
||||
}
|
||||
emit ReputationUpdated(address(_reputation));
|
||||
}
|
||||
|
||||
function setDefaultLockBlocks(
|
||||
uint256 _blocks
|
||||
) public onlyOwner {
|
||||
assembly ("memory-safe") {
|
||||
sstore(defaultLockBlocks.slot, _blocks)
|
||||
}
|
||||
emit LockBlocksUpdated(_blocks);
|
||||
}
|
||||
|
||||
function setValidSigners(
|
||||
address[] memory _validSigners
|
||||
) public onlyOwner {
|
||||
assembly ("memory-safe") {
|
||||
let i := add(_validSigners, 0x20)
|
||||
let end := add(i, shl(0x05, mload(_validSigners)))
|
||||
for {
|
||||
/* */
|
||||
} iszero(returndatasize()) {
|
||||
/* */
|
||||
} {
|
||||
sstore(shl(0xc, mload(i)), true)
|
||||
i := add(i, 0x20)
|
||||
|
||||
if iszero(lt(i, end)) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
emit ValidSignersUpdated(_validSigners);
|
||||
}
|
||||
|
||||
function tokenSettings(
|
||||
ERC20[] memory _tokens,
|
||||
bool[] memory _states
|
||||
) public onlyOwner {
|
||||
/* Yul Impl */
|
||||
assembly ("memory-safe") {
|
||||
// first 32 bytes eq to array's length
|
||||
let tLen := mload(_tokens)
|
||||
// NoTokens()
|
||||
if iszero(tLen) {
|
||||
mstore(0x00, 0xdf957883)
|
||||
revert(0x1c, 0x04)
|
||||
}
|
||||
// LengthMismatch()
|
||||
if iszero(eq(tLen, mload(_states))) {
|
||||
mstore(0x00, 0xff633a38)
|
||||
revert(0x1c, 0x04)
|
||||
}
|
||||
let tLoc := add(_tokens, 0x20)
|
||||
let sLoc := add(_states, 0x20)
|
||||
for {
|
||||
let end := add(tLoc, shl(5, tLen))
|
||||
} iszero(eq(tLoc, end)) {
|
||||
tLoc := add(tLoc, 0x20)
|
||||
sLoc := add(sLoc, 0x20)
|
||||
} {
|
||||
// cache hashmap entry in scratch space
|
||||
mstore(0x0c, _ALLOWED_ERC20_SLOT_SEED)
|
||||
mstore(0x00, mload(tLoc))
|
||||
// let mapSlot := keccak256(0x0c, 0x20)
|
||||
sstore(keccak256(0x0c, 0x20), mload(sLoc))
|
||||
|
||||
// emit AllowedERC20Updated(address, bool)
|
||||
log3(
|
||||
0,
|
||||
0,
|
||||
_ALLOWED_ERC20_UPDATED_EVENT_SIGNATURE,
|
||||
mload(tLoc),
|
||||
mload(sLoc)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// ███ View FX ████████████████████████████████████████████████████████████
|
||||
|
||||
function validBacenSigners(
|
||||
uint256 signer
|
||||
) public view returns (bool valid) {
|
||||
assembly ("memory-safe") {
|
||||
valid := sload(signer)
|
||||
}
|
||||
}
|
||||
|
||||
function sellerAllowList(
|
||||
address sellerKey
|
||||
) public view returns (bytes32 root) {
|
||||
assembly ("memory-safe") {
|
||||
mstore(0x0c, _SELLER_ALLOWLIST_SLOT_SEED)
|
||||
mstore(0x00, sellerKey)
|
||||
root := sload(keccak256(0x00, 0x20))
|
||||
}
|
||||
}
|
||||
|
||||
function allowedERC20s(
|
||||
ERC20 erc20
|
||||
) public view returns (bool state) {
|
||||
assembly ("memory-safe") {
|
||||
mstore(0x0c, _ALLOWED_ERC20_SLOT_SEED)
|
||||
mstore(0x00, erc20)
|
||||
state := sload(keccak256(0x0c, 0x20))
|
||||
}
|
||||
}
|
||||
|
||||
function _limiter(
|
||||
uint256 _userCredit
|
||||
) internal view returns (uint256 _spendLimit) {
|
||||
bytes memory encodedParams = abi.encodeWithSelector(
|
||||
// IReputation.limiter.selector,
|
||||
0x4d2b1791,
|
||||
_userCredit
|
||||
);
|
||||
bool success;
|
||||
assembly ("memory-safe") {
|
||||
success := staticcall(
|
||||
// gas
|
||||
gas(),
|
||||
// address
|
||||
sload(reputation.slot),
|
||||
// argsOffset
|
||||
add(encodedParams, 0x20),
|
||||
// argsSize
|
||||
mload(encodedParams),
|
||||
// retOffset
|
||||
0x00,
|
||||
// retSize
|
||||
0x20
|
||||
)
|
||||
_spendLimit := mload(0x00)
|
||||
if iszero(success) {
|
||||
// StaticCallFailed()
|
||||
mstore(0x00, 0xe10bf1cc)
|
||||
revert(0x1c, 0x04)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity >=0.8.4;
|
||||
|
||||
/// @notice Simple single owner authorization mixin.
|
||||
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)
|
||||
abstract contract Owned {
|
||||
error Unauthorized();
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
EVENTS
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
event OwnerUpdated(
|
||||
address indexed user,
|
||||
address indexed newOwner
|
||||
);
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
OWNERSHIP STORAGE
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
address public owner;
|
||||
|
||||
modifier onlyOwner() virtual {
|
||||
if (msg.sender != owner) revert Unauthorized();
|
||||
|
||||
_;
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
CONSTRUCTOR
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
constructor(address _owner) {
|
||||
owner = _owner;
|
||||
|
||||
emit OwnerUpdated(address(0), _owner);
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
OWNERSHIP LOGIC
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
function setOwner(
|
||||
address newOwner
|
||||
) public virtual onlyOwner {
|
||||
owner = newOwner;
|
||||
|
||||
emit OwnerUpdated(msg.sender, newOwner);
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity >=0.8.4;
|
||||
|
||||
interface IReputation {
|
||||
function limiter(
|
||||
uint256 _userCredit
|
||||
) external pure returns (uint256 _spendLimit);
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity >=0.8.4;
|
||||
|
||||
/// @author OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
|
||||
/// (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Context.sol)
|
||||
|
||||
/// @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;
|
||||
}
|
||||
}
|
||||
|
||||
/// @author Modified from OpenZeppelin Contracts (last updated v4.7.0) (metatx/ERC2771Context.sol)
|
||||
/// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol
|
||||
|
||||
/// @dev Context variant with ERC2771 support.
|
||||
abstract contract ERC2771Context is Context {
|
||||
// address private immutable _trustedForwarder;
|
||||
mapping(address => bool) public trustedForwarders;
|
||||
|
||||
/// @custom:oz-upgrades-unsafe-allow constructor
|
||||
// constructor(address trustedForwarder) {
|
||||
// _trustedForwarder = trustedForwarder;
|
||||
// }
|
||||
|
||||
function _msgSender()
|
||||
internal
|
||||
view
|
||||
virtual
|
||||
override
|
||||
returns (address sender)
|
||||
{
|
||||
if (trustedForwarders[msg.sender]) {
|
||||
// The assembly code is more direct than the Solidity version using `abi.decode`.
|
||||
/// @solidity memory-safe-assembly
|
||||
assembly {
|
||||
sender := shr(
|
||||
96,
|
||||
calldataload(sub(calldatasize(), 20))
|
||||
)
|
||||
}
|
||||
} else {
|
||||
return super._msgSender();
|
||||
}
|
||||
}
|
||||
|
||||
function isTrustedForwarder(address forwarder) public view virtual returns (bool) {
|
||||
return trustedForwarders[forwarder];
|
||||
}
|
||||
|
||||
function _msgData()
|
||||
internal
|
||||
view
|
||||
virtual
|
||||
override
|
||||
returns (bytes calldata)
|
||||
{
|
||||
if (isTrustedForwarder(msg.sender)) {
|
||||
return msg.data[:msg.data.length - 20];
|
||||
} else {
|
||||
return super._msgData();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.19;
|
||||
|
||||
import { ERC20 } from "../tokens/ERC20.sol";
|
||||
|
||||
contract MockToken is ERC20 {
|
||||
constructor(uint256 supply) ERC20("MockBRL", "MBRL", 18) {
|
||||
_mint(msg.sender, supply);
|
||||
}
|
||||
|
||||
function mint(
|
||||
address[] memory to,
|
||||
uint256 value
|
||||
) public virtual {
|
||||
uint256 len = to.length;
|
||||
uint256 j;
|
||||
while (j < len) {
|
||||
_mint(to[j], value);
|
||||
++j;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,250 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity >=0.8.4;
|
||||
|
||||
/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
|
||||
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)
|
||||
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
|
||||
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
|
||||
abstract contract ERC20 {
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
EVENTS
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
event Transfer(
|
||||
address indexed from,
|
||||
address indexed to,
|
||||
uint256 amount
|
||||
);
|
||||
|
||||
event Approval(
|
||||
address indexed owner,
|
||||
address indexed spender,
|
||||
uint256 amount
|
||||
);
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
METADATA STORAGE
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
string public name;
|
||||
|
||||
string public symbol;
|
||||
|
||||
uint8 public immutable decimals;
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
ERC20 STORAGE
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
uint256 public totalSupply;
|
||||
|
||||
mapping(address => uint256) public balanceOf;
|
||||
|
||||
mapping(address => mapping(address => uint256))
|
||||
public allowance;
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
EIP-2612 STORAGE
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
uint256 internal immutable INITIAL_CHAIN_ID;
|
||||
|
||||
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
|
||||
|
||||
mapping(address => uint256) public nonces;
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
CONSTRUCTOR
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
uint8 _decimals
|
||||
) {
|
||||
name = _name;
|
||||
symbol = _symbol;
|
||||
decimals = _decimals;
|
||||
|
||||
INITIAL_CHAIN_ID = block.chainid;
|
||||
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
ERC20 LOGIC
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
function approve(
|
||||
address spender,
|
||||
uint256 amount
|
||||
) public virtual returns (bool) {
|
||||
allowance[msg.sender][spender] = amount;
|
||||
|
||||
emit Approval(msg.sender, spender, amount);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function transfer(
|
||||
address to,
|
||||
uint256 amount
|
||||
) public virtual returns (bool) {
|
||||
balanceOf[msg.sender] -= amount;
|
||||
|
||||
// Cannot overflow because the sum of all user
|
||||
// balances can't exceed the max uint256 value.
|
||||
unchecked {
|
||||
balanceOf[to] += amount;
|
||||
}
|
||||
|
||||
emit Transfer(msg.sender, to, amount);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function transferFrom(
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount
|
||||
) public virtual returns (bool) {
|
||||
uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
|
||||
|
||||
if (allowed != type(uint256).max)
|
||||
allowance[from][msg.sender] = allowed - amount;
|
||||
|
||||
balanceOf[from] -= amount;
|
||||
|
||||
// Cannot overflow because the sum of all user
|
||||
// balances can't exceed the max uint256 value.
|
||||
unchecked {
|
||||
balanceOf[to] += amount;
|
||||
}
|
||||
|
||||
emit Transfer(from, to, amount);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
EIP-2612 LOGIC
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
function permit(
|
||||
address owner,
|
||||
address spender,
|
||||
uint256 value,
|
||||
uint256 deadline,
|
||||
uint8 v,
|
||||
bytes32 r,
|
||||
bytes32 s
|
||||
) public virtual {
|
||||
require(
|
||||
deadline >= block.timestamp,
|
||||
"PERMIT_DEADLINE_EXPIRED"
|
||||
);
|
||||
|
||||
// Unchecked because the only math done is incrementing
|
||||
// the owner's nonce which cannot realistically overflow.
|
||||
unchecked {
|
||||
address recoveredAddress = ecrecover(
|
||||
keccak256(
|
||||
abi.encodePacked(
|
||||
"\x19\x01",
|
||||
DOMAIN_SEPARATOR(),
|
||||
keccak256(
|
||||
abi.encode(
|
||||
keccak256(
|
||||
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
|
||||
),
|
||||
owner,
|
||||
spender,
|
||||
value,
|
||||
nonces[owner]++,
|
||||
deadline
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
v,
|
||||
r,
|
||||
s
|
||||
);
|
||||
|
||||
require(
|
||||
recoveredAddress != address(0) &&
|
||||
recoveredAddress == owner,
|
||||
"INVALID_SIGNER"
|
||||
);
|
||||
|
||||
allowance[recoveredAddress][spender] = value;
|
||||
}
|
||||
|
||||
emit Approval(owner, spender, value);
|
||||
}
|
||||
|
||||
function DOMAIN_SEPARATOR()
|
||||
public
|
||||
view
|
||||
virtual
|
||||
returns (bytes32)
|
||||
{
|
||||
return
|
||||
block.chainid == INITIAL_CHAIN_ID
|
||||
? INITIAL_DOMAIN_SEPARATOR
|
||||
: computeDomainSeparator();
|
||||
}
|
||||
|
||||
function computeDomainSeparator()
|
||||
internal
|
||||
view
|
||||
virtual
|
||||
returns (bytes32)
|
||||
{
|
||||
return
|
||||
keccak256(
|
||||
abi.encode(
|
||||
keccak256(
|
||||
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
|
||||
),
|
||||
keccak256(bytes(name)),
|
||||
keccak256("1"),
|
||||
block.chainid,
|
||||
address(this)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
INTERNAL MINT/BURN LOGIC
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
function _mint(
|
||||
address to,
|
||||
uint256 amount
|
||||
) internal virtual {
|
||||
totalSupply += amount;
|
||||
|
||||
// Cannot overflow because the sum of all user
|
||||
// balances can't exceed the max uint256 value.
|
||||
unchecked {
|
||||
balanceOf[to] += amount;
|
||||
}
|
||||
|
||||
emit Transfer(address(0), to, amount);
|
||||
}
|
||||
|
||||
function _burn(
|
||||
address from,
|
||||
uint256 amount
|
||||
) internal virtual {
|
||||
balanceOf[from] -= amount;
|
||||
|
||||
// Cannot underflow because a user's balance
|
||||
// will never be larger than the total supply.
|
||||
unchecked {
|
||||
totalSupply -= amount;
|
||||
}
|
||||
|
||||
emit Transfer(from, address(0), amount);
|
||||
}
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity >=0.8.4;
|
||||
|
||||
/// @notice Gas optimized ECDSA wrapper.
|
||||
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ECDSA.sol)
|
||||
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ECDSA.sol)
|
||||
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol)
|
||||
library ECDSA {
|
||||
/// @dev The signature is invalid.
|
||||
error InvalidSignature();
|
||||
|
||||
/// @dev The number which `s` must not exceed in order for
|
||||
/// the signature to be non-malleable.
|
||||
bytes32 private constant _MALLEABILITY_THRESHOLD =
|
||||
0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0;
|
||||
|
||||
/// @dev Recovers the signer's address from a message digest `hash`,
|
||||
/// and the `signature`.
|
||||
///
|
||||
/// This function does NOT accept EIP-2098 short form signatures.
|
||||
/// Use `recover(bytes32 hash, bytes32 r, bytes32 vs)` for EIP-2098
|
||||
/// short form signatures instead.
|
||||
function recoverCalldata(
|
||||
bytes32 hash,
|
||||
bytes calldata signature
|
||||
) internal view returns (address result) {
|
||||
/// @solidity memory-safe-assembly
|
||||
assembly {
|
||||
// Copy the free memory pointer so that we can restore it later.
|
||||
let m := mload(0x40)
|
||||
// Directly copy `r` and `s` from the calldata.
|
||||
calldatacopy(0x40, signature.offset, 0x40)
|
||||
// Store the `hash` in the scratch space.
|
||||
mstore(0x00, hash)
|
||||
// Compute `v` and store it in the scratch space.
|
||||
mstore(
|
||||
0x20,
|
||||
byte(
|
||||
0,
|
||||
calldataload(add(signature.offset, 0x40))
|
||||
)
|
||||
)
|
||||
pop(
|
||||
staticcall(
|
||||
gas(), // Amount of gas left for the transaction.
|
||||
and(
|
||||
// If the signature is exactly 65 bytes in length.
|
||||
eq(signature.length, 65),
|
||||
// If `s` in lower half order, such that the signature is not malleable.
|
||||
lt(
|
||||
mload(0x60),
|
||||
add(_MALLEABILITY_THRESHOLD, 1)
|
||||
)
|
||||
), // Address of `ecrecover`.
|
||||
0x00, // Start of input.
|
||||
0x80, // Size of input.
|
||||
0x00, // Start of output.
|
||||
0x20 // Size of output.
|
||||
)
|
||||
)
|
||||
result := mload(0x00)
|
||||
// `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
|
||||
if iszero(returndatasize()) {
|
||||
// Store the function selector of `InvalidSignature()`.
|
||||
mstore(0x00, 0x8baa579f)
|
||||
// Revert with (offset, size).
|
||||
revert(0x1c, 0x04)
|
||||
}
|
||||
// Restore the zero slot.
|
||||
mstore(0x60, 0)
|
||||
// Restore the free memory pointer.
|
||||
mstore(0x40, m)
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Returns an Ethereum Signed Message, created from a `hash`.
|
||||
/// This produces a hash corresponding to the one signed with the
|
||||
/// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign)
|
||||
/// JSON-RPC method as part of EIP-191.
|
||||
function toEthSignedMessageHash(
|
||||
bytes32 hash
|
||||
) internal pure returns (bytes32 result) {
|
||||
/// @solidity memory-safe-assembly
|
||||
assembly {
|
||||
// Store into scratch space for keccak256.
|
||||
mstore(0x20, hash)
|
||||
mstore(
|
||||
0x00,
|
||||
"\x00\x00\x00\x00\x19Ethereum Signed Message:\n32"
|
||||
)
|
||||
// 0x40 - 0x04 = 0x3c
|
||||
result := keccak256(0x04, 0x3c)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity >=0.8.4;
|
||||
|
||||
/// @notice Gas optimized verification of proof of inclusion for a leaf in a Merkle tree.
|
||||
/// @author Solady
|
||||
/// (https://github.com/vectorized/solady/blob/main/src/utils/MerkleProofLib.sol)
|
||||
/// @author Modified from Solmate
|
||||
/// (https://github.com/transmissions11/solmate/blob/main/src/utils/MerkleProofLib.sol)
|
||||
/// @author Modified from OpenZeppelin
|
||||
/// (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/MerkleProof.sol)
|
||||
library MerkleProofLib {
|
||||
/// @dev Returns whether `leaf` exists in the Merkle tree with `root`, given `proof`.
|
||||
function verify(
|
||||
bytes32[] calldata proof,
|
||||
bytes32 root,
|
||||
bytes32 leaf
|
||||
) internal pure returns (bool isValid) {
|
||||
/// @solidity memory-safe-assembly
|
||||
assembly {
|
||||
if proof.length {
|
||||
// Left shift by 5 is equivalent to multiplying by 0x20.
|
||||
let end := add(
|
||||
proof.offset,
|
||||
shl(5, proof.length)
|
||||
)
|
||||
// Initialize `offset` to the offset of `proof` in the calldata.
|
||||
let offset := proof.offset
|
||||
// Iterate over proof elements to compute root hash.
|
||||
for {
|
||||
|
||||
} 1 {
|
||||
|
||||
} {
|
||||
// Slot of `leaf` in scratch space.
|
||||
// If the condition is true: 0x20, otherwise: 0x00.
|
||||
let scratch := shl(
|
||||
5,
|
||||
gt(leaf, calldataload(offset))
|
||||
)
|
||||
// Store elements to hash contiguously in scratch space.
|
||||
// Scratch space is 64 bytes (0x00 - 0x3f) and both elements are 32 bytes.
|
||||
mstore(scratch, leaf)
|
||||
mstore(
|
||||
xor(scratch, 0x20),
|
||||
calldataload(offset)
|
||||
)
|
||||
// Reuse `leaf` to store the hash to reduce stack operations.
|
||||
leaf := keccak256(0x00, 0x40)
|
||||
offset := add(offset, 0x20)
|
||||
if iszero(lt(offset, end)) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
isValid := eq(leaf, root)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity >=0.8.4;
|
||||
|
||||
/// @title Multicall.
|
||||
/// @notice Contract that batches view function calls and aggregates their results.
|
||||
/// @author Adapted from Makerdao's Multicall2 (https://github.com/makerdao/multicall/blob/master/src/Multicall2.sol).
|
||||
|
||||
contract Multicall {
|
||||
/// @dev 0x
|
||||
error CallFailed(string reason);
|
||||
|
||||
struct Call {
|
||||
address target;
|
||||
bytes callData;
|
||||
}
|
||||
struct Result {
|
||||
bool success;
|
||||
bytes returnData;
|
||||
}
|
||||
|
||||
//prettier-ignore
|
||||
constructor(/* */) payable {/* */}
|
||||
|
||||
function mtc1(Call[] calldata calls)
|
||||
external
|
||||
returns (uint256, bytes[] memory)
|
||||
{
|
||||
uint256 bn = block.number;
|
||||
uint256 len = calls.length;
|
||||
bytes[] memory res = new bytes[](len);
|
||||
uint256 j;
|
||||
|
||||
while (j < len) {
|
||||
(bool success, bytes memory ret) = calls[j]
|
||||
.target
|
||||
.call(calls[j].callData);
|
||||
if (!success) {
|
||||
if (ret.length < 0x44) revert CallFailed("");
|
||||
assembly {
|
||||
ret := add(ret, 0x04)
|
||||
}
|
||||
revert CallFailed({
|
||||
reason: abi.decode(ret, (string))
|
||||
});
|
||||
}
|
||||
res[j] = ret;
|
||||
++j;
|
||||
}
|
||||
return (bn, res);
|
||||
}
|
||||
|
||||
function mtc2(Call[] calldata calls)
|
||||
external
|
||||
returns (
|
||||
uint256,
|
||||
bytes32,
|
||||
Result[] memory
|
||||
)
|
||||
{
|
||||
uint256 bn = block.number;
|
||||
// µ 0 s [0] ≡ P(IHp , µs [0], 0) ∴ P is the hash of a block of a particular number, up to a maximum age.
|
||||
// 0 is left on the stack if the looked for `block.number` is >= to the current `block.number` or more than 256
|
||||
// blocks behind the current block (Yellow Paper, p. 33, https://ethereum.github.io/yellowpaper/paper.pdf).
|
||||
bytes32 bh = blockhash(
|
||||
bn /* - 1 */
|
||||
);
|
||||
uint256 len = calls.length;
|
||||
Result[] memory res = new Result[](len);
|
||||
uint256 i;
|
||||
for (i; i < len; ) {
|
||||
(bool success, bytes memory ret) = calls[i]
|
||||
.target
|
||||
.call(calls[i].callData);
|
||||
|
||||
res[i] = Result(success, ret);
|
||||
++i;
|
||||
}
|
||||
return (bn, bh, res);
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity >=0.8.4;
|
||||
|
||||
/// @notice Reentrancy protection for smart contracts.
|
||||
/// @author z0r0z.eth
|
||||
/// @author Modified from Seaport
|
||||
/// (https://github.com/ProjectOpenSea/seaport/blob/main/contracts/lib/ReentrancyGuard.sol)
|
||||
/// @author Modified from Solmate
|
||||
/// (https://github.com/Rari-Capital/solmate/blob/main/src/utils/ReentrancyGuard.sol)
|
||||
abstract contract ReentrancyGuard {
|
||||
error Reentrancy();
|
||||
|
||||
uint256 private guard = 1;
|
||||
|
||||
modifier nonReentrant() virtual {
|
||||
setReentrancyGuard();
|
||||
|
||||
_;
|
||||
|
||||
clearReentrancyGuard();
|
||||
}
|
||||
|
||||
/// @dev Check guard sentinel value and set it.
|
||||
function setReentrancyGuard() internal virtual {
|
||||
if (guard == 2) revert Reentrancy();
|
||||
|
||||
guard = 2;
|
||||
}
|
||||
|
||||
/// @dev Unset sentinel value.
|
||||
function clearReentrancyGuard() internal virtual {
|
||||
guard = 1;
|
||||
}
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity >=0.8.4;
|
||||
|
||||
import { ERC20 } from "../tokens/ERC20.sol";
|
||||
|
||||
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
|
||||
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)
|
||||
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
|
||||
/// @dev Caution! This library won't check that a token has code, responsibility is delegated to the caller.
|
||||
library SafeTransferLib {
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
CUSTOM ERRORS
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
/// @dev The ETH transfer has failed.
|
||||
error ETHTransferFailed();
|
||||
/// @dev The ERC20 `transferFrom` has failed.
|
||||
error TransferFromFailed();
|
||||
/// @dev The ERC20 `transfer` has failed.
|
||||
error TransferFailed();
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
ETH OPERATIONS
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
/// @dev Sends `amount` (in wei) ETH to `to`.
|
||||
/// Reverts upon failure.
|
||||
function safeTransferETH(
|
||||
address to,
|
||||
uint256 amount
|
||||
) internal {
|
||||
/// @solidity memory-safe-assembly
|
||||
assembly {
|
||||
// Transfer the ETH and check if it succeeded or not.
|
||||
if iszero(call(gas(), to, amount, 0, 0, 0, 0)) {
|
||||
// Store the function selector of `ETHTransferFailed()`.
|
||||
mstore(0x00, 0xb12d13eb)
|
||||
// Revert with (offset, size).
|
||||
revert(0x1c, 0x04)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
ERC20 OPERATIONS
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
/// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
|
||||
/// Reverts upon failure.
|
||||
///
|
||||
/// The `from` account must have at least `amount` approved for
|
||||
/// the current contract to manage.
|
||||
function safeTransferFrom(
|
||||
ERC20 token,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount
|
||||
) internal {
|
||||
/// @solidity memory-safe-assembly
|
||||
assembly {
|
||||
let m := mload(0x40) // Cache the free memory pointer.
|
||||
|
||||
mstore(0x60, amount) // Store the `amount` argument.
|
||||
mstore(0x40, to) // Store the `to` argument.
|
||||
mstore(0x2c, shl(96, from)) // Store the `from` argument.
|
||||
// Store the function selector of `transferFrom(address,address,uint256)`.
|
||||
mstore(0x0c, 0x23b872dd000000000000000000000000)
|
||||
|
||||
if iszero(
|
||||
and(
|
||||
// The arguments of `and` are evaluated from right to left.
|
||||
// Set success to whether the call reverted, if not we check it either
|
||||
// returned exactly 1 (can't just be non-zero data), or had no return data.
|
||||
or(
|
||||
eq(mload(0x00), 1),
|
||||
iszero(returndatasize())
|
||||
),
|
||||
call(
|
||||
gas(),
|
||||
token,
|
||||
0,
|
||||
0x1c,
|
||||
0x64,
|
||||
0x00,
|
||||
0x20
|
||||
)
|
||||
)
|
||||
) {
|
||||
// Store the function selector of `TransferFromFailed()`.
|
||||
mstore(0x00, 0x7939f424)
|
||||
// Revert with (offset, size).
|
||||
revert(0x1c, 0x04)
|
||||
}
|
||||
|
||||
mstore(0x60, 0) // Restore the zero slot to zero.
|
||||
mstore(0x40, m) // Restore the free memory pointer.
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.
|
||||
/// Reverts upon failure.
|
||||
function safeTransfer(
|
||||
ERC20 token,
|
||||
address to,
|
||||
uint256 amount
|
||||
) internal {
|
||||
/// @solidity memory-safe-assembly
|
||||
assembly {
|
||||
mstore(0x14, to) // Store the `to` argument.
|
||||
mstore(0x34, amount) // Store the `amount` argument.
|
||||
// Store the function selector of `transfer(address,uint256)`.
|
||||
mstore(0x00, 0xa9059cbb000000000000000000000000)
|
||||
|
||||
if iszero(
|
||||
and(
|
||||
// The arguments of `and` are evaluated from right to left.
|
||||
// Set success to whether the call reverted, if not we check it either
|
||||
// returned exactly 1 (can't just be non-zero data), or had no return data.
|
||||
or(
|
||||
eq(mload(0x00), 1),
|
||||
iszero(returndatasize())
|
||||
),
|
||||
call(
|
||||
gas(),
|
||||
token,
|
||||
0,
|
||||
0x10,
|
||||
0x44,
|
||||
0x00,
|
||||
0x20
|
||||
)
|
||||
)
|
||||
) {
|
||||
// Store the function selector of `TransferFailed()`.
|
||||
mstore(0x00, 0x90b8ec18)
|
||||
// Revert with (offset, size).
|
||||
revert(0x1c, 0x04)
|
||||
}
|
||||
// Restore the part of the free memory pointer that was overwritten.
|
||||
mstore(0x34, 0)
|
||||
}
|
||||
}
|
||||
}
|
11
contracts/mockToken.sol
Normal file
11
contracts/mockToken.sol
Normal file
@ -0,0 +1,11 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.9;
|
||||
|
||||
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
||||
|
||||
contract MockToken is ERC20 {
|
||||
|
||||
constructor(uint256 supply) ERC20("MockBRL", "MBRL") {
|
||||
_mint(msg.sender, supply);
|
||||
}
|
||||
}
|
@ -1,554 +1,183 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.19;
|
||||
pragma solidity ^0.8.9;
|
||||
|
||||
/// ______ __
|
||||
/// .-----.|__ |.-----.|__|.--.--.
|
||||
/// | _ || __|| _ || ||_ _|
|
||||
/// | __||______|| __||__||__.__|
|
||||
/// |__| |__|
|
||||
///
|
||||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import "@openzeppelin/contracts/access/Ownable.sol";
|
||||
|
||||
import { OwnerSettings, ERC20, SafeTransferLib } from "contracts/core/OwnerSettings.sol";
|
||||
import { BaseUtils } from "contracts/core/BaseUtils.sol";
|
||||
import { DataTypes as DT } from "contracts/core/DataTypes.sol";
|
||||
contract P2PIX is Ownable {
|
||||
|
||||
event DepositAdded(address indexed seller, bytes32 depositID, address token, uint256 premium, uint256 amount);
|
||||
event DepositClosed(address indexed seller, bytes32 depositID);
|
||||
event DepositWithdrawn(address indexed seller, bytes32 depositID, uint256 amount);
|
||||
event LockAdded(address indexed buyer, bytes32 indexed lockID, bytes32 depositID, uint256 amount);
|
||||
event LockReleased(address indexed buyer, bytes32 lockId);
|
||||
event LockReturned(address indexed buyer, bytes32 lockId);
|
||||
// Events
|
||||
event PremiumsWithdrawn(address owner, uint256 amount);
|
||||
|
||||
contract P2PIX is BaseUtils {
|
||||
// solhint-disable use-forbidden-name
|
||||
// solhint-disable no-inline-assembly
|
||||
// solhint-disable no-empty-blocks
|
||||
struct Deposit {
|
||||
address seller;
|
||||
address token; // ERC20 stable token address
|
||||
uint256 remaining; // Remaining tokens available
|
||||
uint256 premium; // Premium paid in ETH for priority
|
||||
bool valid; // Could be invalidated by the seller
|
||||
string pixTarget; // The PIX account for the seller receive transactions
|
||||
}
|
||||
|
||||
using DT for DT.Lock;
|
||||
using DT for DT.LockStatus;
|
||||
struct Lock {
|
||||
bytes32 depositID;
|
||||
address targetAddress; // Where goes the tokens when validated
|
||||
address relayerAddress; // Relayer address that facilitated this transaction
|
||||
uint256 relayerPremium; // Amount to be paid for relayer
|
||||
uint256 amount; // Amount to be tranfered via PIX
|
||||
uint256 expirationBlock; // If not paid at this block will be expired
|
||||
}
|
||||
|
||||
uint256 public lockCounter;
|
||||
// Default blocks that lock will hold tokens
|
||||
uint256 public defaultLockBlocks;
|
||||
// List of valid Bacen signature addresses
|
||||
mapping(address => bool) public validBacenSigners;
|
||||
|
||||
/// @dev List of Locks.
|
||||
mapping(uint256 => DT.Lock) public mapLocks;
|
||||
/// @dev Stores an relayer's last computed credit.
|
||||
mapping(uint256 => uint256) public userRecord;
|
||||
// Seller list of deposits
|
||||
mapping(bytes32 => Deposit) mapDeposits;
|
||||
// List of Locks
|
||||
mapping(bytes32 => Lock) mapLocks;
|
||||
// List of Pix transactions already signed
|
||||
mapping(bytes32 => bool) usedTransactions;
|
||||
|
||||
constructor(
|
||||
uint256 defaultBlocks,
|
||||
address[] memory validSigners,
|
||||
address _reputation,
|
||||
ERC20[] memory tokens,
|
||||
bool[] memory tokenStates
|
||||
)
|
||||
OwnerSettings(
|
||||
defaultBlocks,
|
||||
validSigners,
|
||||
_reputation,
|
||||
tokens,
|
||||
tokenStates
|
||||
)
|
||||
payable {/* */}
|
||||
modifier onlySeller(bytes32 depositID) {
|
||||
require(mapDeposits[depositID].seller == msg.sender, "P2PIX: Only seller could call this function.");
|
||||
_;
|
||||
}
|
||||
|
||||
/// @notice Creates a deposit order based on a seller's
|
||||
/// offer of an amount of ERC20 tokens.
|
||||
/// @notice Seller needs to send his tokens to the P2PIX smart contract.
|
||||
/// @param pixTarget Pix key destination provided by the offer's seller.
|
||||
/// @param allowlistRoot Optional allow list merkleRoot update `bytes32` value.
|
||||
/// as the deposit identifier.
|
||||
/// @dev Function sighash: 0x5e918943
|
||||
constructor (uint256 defaultBlocks, address[] memory validSigners) Ownable() {
|
||||
defaultLockBlocks = defaultBlocks;
|
||||
for (uint8 i = 0; i < validSigners.length; i++){
|
||||
validBacenSigners[validSigners[i]] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Vendedor precisa mandar token para o smart contract + chave PIX destino. Retorna um DepositID.
|
||||
function deposit(
|
||||
string calldata pixTarget,
|
||||
bytes32 allowlistRoot,
|
||||
ERC20 token,
|
||||
uint96 amount,
|
||||
bool valid
|
||||
) public nonReentrant {
|
||||
|
||||
if (bytes(pixTarget).length == 0) revert EmptyPixTarget();
|
||||
if (!allowedERC20s(token)) revert TokenDenied();
|
||||
uint256 _sellerBalance = __sellerBalance(msg.sender, token);
|
||||
|
||||
uint256 currBal = _sellerBalance & BITMASK_SB_ENTRY;
|
||||
uint256 _newBal = uint256(currBal + amount);
|
||||
if (_newBal > MAXBALANCE_UPPERBOUND)
|
||||
revert MaxBalExceeded();
|
||||
|
||||
if (allowlistRoot != 0) {
|
||||
setRoot(msg.sender, allowlistRoot);
|
||||
}
|
||||
|
||||
bytes32 pixTargetCasted = getStr(pixTarget);
|
||||
uint256 validCasted = _castBool(valid);
|
||||
|
||||
_setSellerBalance(
|
||||
msg.sender,
|
||||
token,
|
||||
(_newBal | (validCasted << BITPOS_VALID)),
|
||||
pixTargetCasted
|
||||
);
|
||||
|
||||
SafeTransferLib.safeTransferFrom(
|
||||
token,
|
||||
msg.sender,
|
||||
address(this),
|
||||
amount
|
||||
);
|
||||
|
||||
emit DepositAdded(msg.sender, token, amount);
|
||||
address token,
|
||||
uint256 amount,
|
||||
string calldata pixTarget
|
||||
) public payable returns (bytes32 depositID){
|
||||
depositID = keccak256(abi.encodePacked(pixTarget, amount));
|
||||
require(!mapDeposits[depositID].valid, 'P2PIX: Deposit already exist and it is still valid');
|
||||
IERC20 t = IERC20(token);
|
||||
t.transferFrom(msg.sender, address(this), amount);
|
||||
Deposit memory d = Deposit(msg.sender, token, amount, msg.value, true, pixTarget);
|
||||
mapDeposits[depositID] = d;
|
||||
emit DepositAdded(msg.sender, depositID, token, msg.value, amount);
|
||||
}
|
||||
|
||||
/// @notice Enables seller to invalidate future
|
||||
/// locks made to his/her token offering order.
|
||||
/// @notice This function does not affect any ongoing active locks.
|
||||
/// @dev Function sighash: 0x6d82d9e0
|
||||
function setValidState(ERC20 token, bool state) public {
|
||||
uint256 _sellerBalance = __sellerBalance(msg.sender, token);
|
||||
|
||||
if (_sellerBalance != 0) {
|
||||
uint256 _valid = _castBool(state);
|
||||
|
||||
_sellerBalance =
|
||||
(_sellerBalance & BITMASK_SB_ENTRY) |
|
||||
(_valid << BITPOS_VALID);
|
||||
|
||||
_setValidState(msg.sender, token, _sellerBalance);
|
||||
|
||||
emit ValidSet(msg.sender, token, state);
|
||||
} else revert NotInitialized();
|
||||
// Vendedor pode invalidar da ordem de venda impedindo novos locks na mesma (isso não afeta nenhum lock que esteja ativo).
|
||||
function cancelDeposit(bytes32 depositID) public onlySeller(depositID) {
|
||||
mapDeposits[depositID].valid = false;
|
||||
emit DepositClosed(mapDeposits[depositID].seller, depositID);
|
||||
}
|
||||
|
||||
/// @notice Public method designed to lock an remaining amount of
|
||||
/// the deposit order of a seller.
|
||||
/// @notice Transaction forwarding must leave `merkleProof` empty;
|
||||
/// otherwise, the trustedForwarder must be previously added
|
||||
/// to a seller whitelist.
|
||||
/// @notice This method can be performed either by:
|
||||
/// - An user allowed via the seller's allowlist;
|
||||
/// - An user with enough userRecord to lock the wished amount;
|
||||
/// @notice There can only exist a lock per each `amount` partitioned
|
||||
/// from the total `remaining` value.
|
||||
/// @notice Locks can only be performed in valid orders.
|
||||
/// @param amount The deposit's remaining amount wished to be locked.
|
||||
/// @param merkleProof Provided as a pass if the `msg.sender` is in the
|
||||
/// seller's allowlist; Left empty otherwise;
|
||||
/// @param expiredLocks An array of identifiers to be
|
||||
/// provided so to unexpire locks using this transaction gas push.
|
||||
/// @return lockID The lock identifier.
|
||||
/// @dev Function sighash: 0xdc43221c
|
||||
// Relayer interaje adicionando um “lock” na ordem de venda.
|
||||
// O lock precisa incluir address do comprador + address do relayer + reembolso/premio relayer + valor.
|
||||
// **Só poder ter um lock em aberto para cada (ordem de venda, valor)**.
|
||||
// Só pode fazer lock de ordens que não estão invalidadas(Passo 5).
|
||||
// Essa etapa pode ser feita pelo vendedor conjuntamente com a parte 1.
|
||||
// Retorna um LockID.
|
||||
function lock(
|
||||
address seller,
|
||||
ERC20 token,
|
||||
uint80 amount,
|
||||
bytes32[] calldata merkleProof,
|
||||
uint256[] calldata expiredLocks
|
||||
) public nonReentrant returns (uint256 lockID) {
|
||||
bytes32 depositID,
|
||||
address targetAddress,
|
||||
address relayerAddress,
|
||||
uint256 relayerPremium,
|
||||
uint256 amount,
|
||||
bytes32[] calldata expiredLocks
|
||||
) public returns (bytes32 lockID){
|
||||
unlockExpired(expiredLocks);
|
||||
|
||||
if (!getValid(seller, token)) revert InvalidDeposit();
|
||||
|
||||
uint256 bal = getBalance(seller, token);
|
||||
if (bal < amount) revert NotEnoughTokens();
|
||||
|
||||
unchecked {
|
||||
lockID = ++lockCounter;
|
||||
}
|
||||
|
||||
if (
|
||||
mapLocks[lockID].expirationBlock >= block.number
|
||||
) revert NotExpired();
|
||||
|
||||
bytes32 _pixTarget = getPixTarget(seller, token);
|
||||
|
||||
// transaction forwarding must leave `merkleProof` empty;
|
||||
// otherwise, the trustedForwarder must be previously added
|
||||
// to a seller whitelist.
|
||||
if (merkleProof.length != 0) {
|
||||
_merkleVerify( merkleProof, sellerAllowList(seller), _msgSender());
|
||||
|
||||
} else if ( amount > REPUTATION_LOWERBOUND && msg.sender == _msgSender() ) {
|
||||
|
||||
uint256 spendLimit; uint256 userCredit =
|
||||
userRecord[_castAddrToKey(_msgSender())];
|
||||
(spendLimit) = _limiter(userCredit / WAD);
|
||||
if (
|
||||
amount > (spendLimit * WAD) ||
|
||||
amount > LOCKAMOUNT_UPPERBOUND
|
||||
) revert AmountNotAllowed();
|
||||
}
|
||||
|
||||
DT.Lock memory l = DT.Lock(
|
||||
lockID,
|
||||
(block.number + defaultLockBlocks),
|
||||
_pixTarget,
|
||||
amount,
|
||||
token,
|
||||
_msgSender(),
|
||||
seller
|
||||
Deposit storage d = mapDeposits[depositID];
|
||||
require(d.valid, "P2PIX: Deposit not valid anymore");
|
||||
require(d.remaining >= amount, "P2PIX: Not enough token remaining on deposit");
|
||||
lockID = keccak256(abi.encodePacked(depositID, amount, targetAddress));
|
||||
require(
|
||||
mapLocks[lockID].expirationBlock < block.number,
|
||||
"P2PIX: Another lock with same ID is not expired yet"
|
||||
);
|
||||
|
||||
_addLock(bal, l);
|
||||
Lock memory l = Lock(
|
||||
depositID,
|
||||
targetAddress,
|
||||
relayerAddress,
|
||||
relayerPremium,
|
||||
amount,
|
||||
block.number+defaultLockBlocks
|
||||
);
|
||||
mapLocks[lockID] = l;
|
||||
d.remaining -= amount;
|
||||
emit LockAdded(targetAddress, lockID, depositID, amount);
|
||||
}
|
||||
|
||||
/// @notice Lock release method that liquidate lock
|
||||
/// orders and distributes relayer fees.
|
||||
/// @notice This method can be called by any public actor
|
||||
/// as long the signature provided is valid.
|
||||
/// @notice `relayerPremium` gets splitted equaly
|
||||
/// if relayer addresses differ.
|
||||
/// @notice If the `msg.sender` of this method and `l.relayerAddress` are the same,
|
||||
/// `msg.sender` accrues both l.amount and l.relayerPremium as userRecord credit.
|
||||
/// In case of they differing:
|
||||
/// - `lock` caller gets accrued with `l.amount` as userRecord credit;
|
||||
/// - `release` caller gets accrued with `l.relayerPremium` as userRecord credit;
|
||||
/// @dev Function sighash: 0x11fc7f9a
|
||||
// Relayer interage com o smart contract, colocando no calldata o comprovante do PIX realizado.
|
||||
// Smart contract valida o comprovante, manda os tokens para o endereço do pagador, e reembolsa o custo do gás para o endereço do relayer especificado na parte (2).
|
||||
function release(
|
||||
uint256 lockID,
|
||||
bytes32 pixTimestamp,
|
||||
bytes calldata signature
|
||||
) public nonReentrant {
|
||||
DT.Lock storage l = mapLocks[lockID];
|
||||
|
||||
if (l.amount == 0) revert AlreadyReleased();
|
||||
if (l.expirationBlock < block.number)
|
||||
revert LockExpired();
|
||||
|
||||
bytes32 message = keccak256(
|
||||
abi.encodePacked(
|
||||
l.pixTarget,
|
||||
l.amount,
|
||||
pixTimestamp
|
||||
)
|
||||
);
|
||||
|
||||
_signerCheck(message, signature);
|
||||
|
||||
ERC20 t = ERC20(l.token);
|
||||
|
||||
// We cache lockAmount value before zeroing it out.
|
||||
uint256 lockAmount = l.amount;
|
||||
|
||||
bytes32 lockID,
|
||||
uint256 pixTimestamp,
|
||||
bytes32 r,
|
||||
bytes32 s,
|
||||
uint8 v
|
||||
) public {
|
||||
// TODO **Prevenir que um Pix não relacionado ao APP seja usado pois tem o mesmo destino
|
||||
Lock storage l = mapLocks[lockID];
|
||||
require(l.expirationBlock > block.number && l.amount > 0, "P2PIX: Lock already released or returned");
|
||||
Deposit storage d = mapDeposits[l.depositID];
|
||||
bytes32 message = keccak256(abi.encodePacked(
|
||||
mapDeposits[l.depositID].pixTarget,
|
||||
l.amount,
|
||||
pixTimestamp
|
||||
));
|
||||
bytes32 messageDigest = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
|
||||
require(!usedTransactions[message], "P2PIX: Transaction already used to unlock payment");
|
||||
address signer = ecrecover(messageDigest, v, r, s);
|
||||
require(validBacenSigners[signer], "P2PIX: Signer is not a valid signer");
|
||||
IERC20 t = IERC20(d.token);
|
||||
t.transfer(l.targetAddress, l.amount-l.relayerPremium);
|
||||
if (l.relayerPremium > 0) t.transfer(l.relayerAddress, l.relayerPremium);
|
||||
l.amount = 0;
|
||||
l.expirationBlock = 0;
|
||||
_setUsedTransactions(message);
|
||||
|
||||
if (_msgSender() == msg.sender) {
|
||||
if (msg.sender != l.buyerAddress) {
|
||||
userRecord[_castAddrToKey(msg.sender)] += (lockAmount >> 1);
|
||||
userRecord[_castAddrToKey(l.buyerAddress)] += (lockAmount >> 1);
|
||||
} else {
|
||||
userRecord[_castAddrToKey(msg.sender)] += lockAmount;
|
||||
}}
|
||||
|
||||
SafeTransferLib.safeTransfer(
|
||||
t,
|
||||
l.buyerAddress,
|
||||
lockAmount
|
||||
);
|
||||
|
||||
emit LockReleased(l.buyerAddress, lockID, lockAmount);
|
||||
usedTransactions[message] = true;
|
||||
emit LockReleased(l.targetAddress, lockID);
|
||||
}
|
||||
|
||||
/// @notice Unlocks expired locks.
|
||||
/// @notice Triggered in the callgraph by both `lock` and `withdraw` functions.
|
||||
/// @notice This method can also have any public actor as its `tx.origin`.
|
||||
/// @notice For each successfull unexpired lock recovered,
|
||||
/// `userRecord[_castAddrToKey(l.relayerAddress)]` is decreased by half of its value.
|
||||
/// @dev Function sighash: 0xb0983d39
|
||||
function unlockExpired(uint256[] calldata lockIDs)
|
||||
public
|
||||
{
|
||||
uint256 i;
|
||||
// Unlock expired locks
|
||||
function unlockExpired(bytes32[] calldata lockIDs) public {
|
||||
uint256 locksSize = lockIDs.length;
|
||||
|
||||
for (i; i < locksSize; ) {
|
||||
DT.Lock storage l = mapLocks[lockIDs[i]];
|
||||
|
||||
_notExpired(l);
|
||||
|
||||
uint256 _sellerBalance =
|
||||
__sellerBalance(l.seller, l.token) & BITMASK_SB_ENTRY;
|
||||
|
||||
if ((_sellerBalance + l.amount) > MAXBALANCE_UPPERBOUND)
|
||||
revert MaxBalExceeded();
|
||||
|
||||
_addSellerBalance(l.seller, l.token, l.amount);
|
||||
|
||||
for (uint16 i = 0; i < locksSize; i++){
|
||||
Lock storage l = mapLocks[lockIDs[i]];
|
||||
require(l.expirationBlock < block.number && l.amount > 0, "P2PIX: Lock not expired or already released");
|
||||
mapDeposits[l.depositID].remaining += l.amount;
|
||||
l.amount = 0;
|
||||
|
||||
uint256 userKey = _castAddrToKey(
|
||||
l.buyerAddress
|
||||
);
|
||||
uint256 _newUserRecord = (userRecord[userKey] >>
|
||||
1);
|
||||
|
||||
if (_newUserRecord <= REPUTATION_LOWERBOUND) {
|
||||
userRecord[userKey] = REPUTATION_LOWERBOUND;
|
||||
} else {
|
||||
userRecord[userKey] = _newUserRecord;
|
||||
}
|
||||
emit LockReturned(l.buyerAddress, lockIDs[i]);
|
||||
|
||||
unchecked {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
assembly ("memory-safe") {
|
||||
if lt(i, locksSize) {
|
||||
// LoopOverflow()
|
||||
mstore(0x00, 0xdfb035c9)
|
||||
revert(0x1c, 0x04)
|
||||
}
|
||||
emit LockReturned(l.targetAddress, lockIDs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// @notice Seller's expired deposit fund sweeper.
|
||||
/// @notice A seller may use this method to recover
|
||||
/// tokens from expired deposits.
|
||||
/// @dev Function sighash: 0xfb8c5ef0
|
||||
// Após os locks expirarem, vendedor pode interagir c/ o contrato e recuperar os tokens de um depósito específico.
|
||||
function withdraw(
|
||||
ERC20 token,
|
||||
uint256 amount,
|
||||
uint256[] calldata expiredLocks
|
||||
) public nonReentrant {
|
||||
bytes32 depositID,
|
||||
bytes32[] calldata expiredLocks
|
||||
) public onlySeller(depositID) {
|
||||
unlockExpired(expiredLocks);
|
||||
|
||||
if (getValid(msg.sender, token))
|
||||
setValidState(token, false);
|
||||
|
||||
_decBal(
|
||||
(__sellerBalance(msg.sender, token) & BITMASK_SB_ENTRY),
|
||||
amount,
|
||||
token,
|
||||
msg.sender
|
||||
);
|
||||
|
||||
// safeTransfer tokens to seller
|
||||
SafeTransferLib.safeTransfer(
|
||||
token,
|
||||
msg.sender,
|
||||
amount
|
||||
);
|
||||
|
||||
emit DepositWithdrawn(
|
||||
msg.sender,
|
||||
token,
|
||||
amount
|
||||
);
|
||||
Deposit storage d = mapDeposits[depositID];
|
||||
if (d.valid) cancelDeposit(depositID);
|
||||
IERC20 token = IERC20(d.token);
|
||||
// Withdraw remaining tokens from mapDeposit[depositID]
|
||||
token.transfer(d.seller, d.remaining);
|
||||
uint256 amount = d.remaining;
|
||||
d.remaining = 0;
|
||||
emit DepositWithdrawn(msg.sender, depositID, amount);
|
||||
}
|
||||
|
||||
function setRoot(address addr, bytes32 merkleroot)
|
||||
public
|
||||
{
|
||||
assembly ("memory-safe") {
|
||||
// if (addr != msg.sender)
|
||||
if iszero(eq(addr, caller())) {
|
||||
// revert OnlySeller()
|
||||
mstore(0x00, 0x85d1f726)
|
||||
revert(0x1c, 0x04)
|
||||
}
|
||||
// sets root to SellerAllowlist's storage slot
|
||||
mstore(0x0c, _SELLER_ALLOWLIST_SLOT_SEED)
|
||||
mstore(0x00, addr)
|
||||
sstore(keccak256(0x00, 0x20), merkleroot)
|
||||
|
||||
// emit RootUpdated(addr, merkleroot);
|
||||
log3(
|
||||
0,
|
||||
0,
|
||||
_ROOT_UPDATED_EVENT_SIGNATURE,
|
||||
addr,
|
||||
merkleroot
|
||||
)
|
||||
}
|
||||
// O dono do contrato pode sacar os premiums pagos
|
||||
function withdrawPremiums() external onlyOwner {
|
||||
uint256 balance = address(this).balance;
|
||||
payable(msg.sender).transfer(balance);
|
||||
emit PremiumsWithdrawn(msg.sender, balance);
|
||||
}
|
||||
|
||||
// solhint-disable-next-line no-empty-blocks
|
||||
receive() external payable {}
|
||||
|
||||
/// @notice Private view auxiliar logic that reverts
|
||||
/// on a not expired lock passed as argument of the function.
|
||||
/// @dev Called exclusively by the `unlockExpired` method.
|
||||
function _notExpired(DT.Lock storage _l) private view {
|
||||
if (_l.expirationBlock > block.number)
|
||||
revert NotExpired();
|
||||
if (_l.amount == 0) revert AlreadyReleased();
|
||||
}
|
||||
|
||||
function _addLock(
|
||||
uint256 _bal,
|
||||
DT.Lock memory _l
|
||||
) internal {
|
||||
mapLocks[_l.counter] = _l;
|
||||
|
||||
_decBal(_bal, _l.amount, ERC20(_l.token), _l.seller);
|
||||
|
||||
emit LockAdded(
|
||||
_l.buyerAddress,
|
||||
_l.counter,
|
||||
_l.seller,
|
||||
_l.amount
|
||||
);
|
||||
}
|
||||
|
||||
function _decBal(
|
||||
uint256 _bal,
|
||||
uint256 _amount,
|
||||
ERC20 _t,
|
||||
address _k
|
||||
) private {
|
||||
assembly ("memory-safe") {
|
||||
if iszero(
|
||||
iszero(
|
||||
or(
|
||||
iszero(_bal),
|
||||
gt(sub(_bal, _amount), _bal)
|
||||
)
|
||||
)
|
||||
) {
|
||||
// DecOverflow()
|
||||
mstore(0x00, 0xce3a3d37)
|
||||
revert(0x1c, 0x04)
|
||||
}
|
||||
}
|
||||
|
||||
// we can directly dec from packed uint entry value
|
||||
_decSellerBalance(_k,_t, _amount);
|
||||
}
|
||||
|
||||
function getBalance(address seller, ERC20 token)
|
||||
public
|
||||
view
|
||||
returns (uint256 bal)
|
||||
{
|
||||
assembly ("memory-safe") {
|
||||
for {
|
||||
/* */
|
||||
} iszero(returndatasize()) {
|
||||
/* */
|
||||
} {
|
||||
mstore(0x20, token)
|
||||
mstore(0x0c, _SELLER_BALANCE_SLOT_SEED)
|
||||
mstore(0x00, seller)
|
||||
bal := and(
|
||||
BITMASK_SB_ENTRY,
|
||||
sload(add(keccak256(0x0c, 0x34), 0x01))
|
||||
)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getValid(address seller, ERC20 token)
|
||||
public
|
||||
view
|
||||
returns (bool valid)
|
||||
{
|
||||
assembly ("memory-safe") {
|
||||
for {
|
||||
/* */
|
||||
} iszero(returndatasize()) {
|
||||
/* */
|
||||
} {
|
||||
mstore(0x20, token)
|
||||
mstore(0x0c, _SELLER_BALANCE_SLOT_SEED)
|
||||
mstore(0x00, seller)
|
||||
valid := and(
|
||||
BITMASK_SB_ENTRY,
|
||||
shr(
|
||||
BITPOS_VALID,
|
||||
sload(add(keccak256(0x0c, 0x34), 0x01))
|
||||
)
|
||||
)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getPixTarget(address seller, ERC20 token)
|
||||
public
|
||||
view
|
||||
returns (bytes32 pixTarget)
|
||||
{
|
||||
assembly ("memory-safe") {
|
||||
for {
|
||||
/* */
|
||||
} iszero(returndatasize()) {
|
||||
/* */
|
||||
} {
|
||||
mstore(0x20, token)
|
||||
mstore(0x0c, _SELLER_BALANCE_SLOT_SEED)
|
||||
mstore(0x00, seller)
|
||||
pixTarget := sload(keccak256(0x0c, 0x34))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getPixTargetString(address seller, ERC20 token) public view returns (string memory pixTarget) {
|
||||
bytes32 _pixEnc = getPixTarget(seller, token);
|
||||
pixTarget = string(abi.encodePacked(_pixEnc));
|
||||
}
|
||||
|
||||
function getBalances(
|
||||
address[] memory sellers,
|
||||
ERC20 token
|
||||
) external view returns (uint256[] memory) {
|
||||
uint256 j;
|
||||
uint256 len = sellers.length;
|
||||
uint256[] memory balances = new uint256[](len);
|
||||
while (j < len) {
|
||||
uint256 bal = getBalance(sellers[j], token);
|
||||
balances[j] = bal;
|
||||
unchecked {
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
||||
return balances;
|
||||
}
|
||||
|
||||
/// @notice External getter that returns the status of a lockIDs array.
|
||||
/// @notice Call will not revert if provided with an empty array as parameter.
|
||||
/// @dev Function sighash: 0x49ef8448
|
||||
function getLocksStatus(uint256[] memory ids)
|
||||
external
|
||||
view
|
||||
returns (uint256[] memory, DT.LockStatus[] memory)
|
||||
{
|
||||
if (ids.length == 0) {
|
||||
uint256[] memory null1 = new uint256[](0);
|
||||
DT.LockStatus[]
|
||||
memory null2 = new DT.LockStatus[](0);
|
||||
return (null1, null2);
|
||||
}
|
||||
|
||||
uint256 c;
|
||||
uint256 len = ids.length;
|
||||
|
||||
uint256[] memory sortedIDs = new uint256[](len);
|
||||
DT.LockStatus[] memory status = new DT.LockStatus[](
|
||||
len
|
||||
);
|
||||
unchecked {
|
||||
for (c; c < len; ) {
|
||||
if (mapLocks[ids[c]].seller == address(0)) {
|
||||
sortedIDs[c] = ids[c];
|
||||
status[c] = type(DT.LockStatus).min;
|
||||
++c;
|
||||
} else if (mapLocks[ids[c]].amount == 0x0) {
|
||||
sortedIDs[c] = ids[c];
|
||||
status[c] = type(DT.LockStatus).max;
|
||||
++c;
|
||||
} else if (
|
||||
mapLocks[ids[c]].expirationBlock <
|
||||
block.number
|
||||
) {
|
||||
sortedIDs[c] = ids[c];
|
||||
status[c] = DT.LockStatus.Expired;
|
||||
++c;
|
||||
} else {
|
||||
sortedIDs[c] = ids[c];
|
||||
status[c] = DT.LockStatus.Active;
|
||||
++c;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (sortedIDs, status);
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"signers": [
|
||||
"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
|
||||
"0x70997970C51812dc3A010C7d01b50e0d17dc79C8"
|
||||
],
|
||||
"p2pix": "0x2414817FF64A114d91eCFA16a834d3fCf69103d4",
|
||||
"token": "0x4A2886EAEc931e04297ed336Cc55c4eb7C75BA00"
|
||||
}
|
@ -3,6 +3,6 @@
|
||||
"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
|
||||
"0x70997970C51812dc3A010C7d01b50e0d17dc79C8"
|
||||
],
|
||||
"p2pix": "0xC86042E9F2977C62Da8c9dDF7F9c40fde4796A29",
|
||||
"token": "0xD38D6367f452D097ccBfDe4490b7de570B6A72Db"
|
||||
"p2pix": "0x5FbDB2315678afecb367f032d93F642f64180aa3",
|
||||
"token": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512"
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"signers": [
|
||||
"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
|
||||
"0x70997970C51812dc3A010C7d01b50e0d17dc79C8"
|
||||
],
|
||||
"p2pix": "0x4A2886EAEc931e04297ed336Cc55c4eb7C75BA00",
|
||||
"token": "0xC86042E9F2977C62Da8c9dDF7F9c40fde4796A29"
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"signers": [
|
||||
"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
|
||||
"0x70997970C51812dc3A010C7d01b50e0d17dc79C8"
|
||||
],
|
||||
"token": "0xfE841c74250e57640390f46d914C88d22C51e82e",
|
||||
"p2pix": "0x98ba35eb14b38D6Aa709338283af3e922476dE34"
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"signers": [
|
||||
"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
|
||||
"0x70997970C51812dc3A010C7d01b50e0d17dc79C8"
|
||||
],
|
||||
"p2pix": "0xb7cD135F5eFD9760981e02E2a898790b688939fe",
|
||||
"token": "0x3eBE67A2C7bdB2081CBd34ba3281E90377462289"
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
# Solidity API
|
||||
|
||||
## Reputation
|
||||
|
||||
### maxLimit
|
||||
|
||||
```solidity
|
||||
uint256 maxLimit
|
||||
```
|
||||
|
||||
_Asymptote numerator constant value for the `limiter` fx._
|
||||
|
||||
### magicValue
|
||||
|
||||
```solidity
|
||||
uint256 magicValue
|
||||
```
|
||||
|
||||
_Denominator's constant operand for the `limiter` fx._
|
||||
|
||||
### constructor
|
||||
|
||||
```solidity
|
||||
constructor() public payable
|
||||
```
|
||||
|
||||
### limiter
|
||||
|
||||
```solidity
|
||||
function limiter(uint256 _userCredit) external pure returns (uint256 _spendLimit)
|
||||
```
|
||||
|
||||
### sqrt
|
||||
|
||||
```solidity
|
||||
function sqrt(uint256 x) internal pure returns (uint256 z)
|
||||
```
|
||||
|
||||
Taken from Solmate's FixedPointMathLib.
|
||||
(https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
|
||||
|
@ -1,957 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="841pt" height="1998pt" viewBox="0.00 0.00 841.22 1998.00">
|
||||
<g id="graph0" class="graph" transform="translate(4,1994) scale(1)" data-name="G">
|
||||
|
||||
<polygon fill="#2e3e56" stroke="none" points="-4,4 -4,-1994 837.22,-1994 837.22,4 -4,4" style=""/>
|
||||
<g id="clust1" class="cluster" data-name="clusterP2PIX">
|
||||
|
||||
<path fill="#445773" stroke="#445773" d="M20,-286C20,-286 813.22,-286 813.22,-286 819.22,-286 825.22,-292 825.22,-298 825.22,-298 825.22,-1833 825.22,-1833 825.22,-1839 819.22,-1845 813.22,-1845 813.22,-1845 20,-1845 20,-1845 14,-1845 8,-1839 8,-1833 8,-1833 8,-298 8,-298 8,-292 14,-286 20,-286" style=""/>
|
||||
<text text-anchor="middle" x="416.61" y="-1828.4" font-family="Times,serif" font-size="14.00" fill="#f0f0f0" style="">P2PIX</text>
|
||||
</g>
|
||||
<g id="clust2" class="cluster" data-name="clusterSafeTransferLib">
|
||||
|
||||
<path fill="#3b4b63" stroke="#e8726d" stroke-dasharray="5,2" d="M456.84,-8C456.84,-8 609.27,-8 609.27,-8 615.27,-8 621.27,-14 621.27,-20 621.27,-20 621.27,-181 621.27,-181 621.27,-187 615.27,-193 609.27,-193 609.27,-193 456.84,-193 456.84,-193 450.84,-193 444.84,-187 444.84,-181 444.84,-181 444.84,-20 444.84,-20 444.84,-14 450.84,-8 456.84,-8" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-176.4" font-family="Times,serif" font-size="14.00" fill="#f0f0f0" style="">SafeTransferLib</text>
|
||||
</g>
|
||||
<g id="clust3" class="cluster" data-name="clusterDT">
|
||||
|
||||
<path fill="#3b4b63" stroke="#e8726d" stroke-dasharray="5,2" d="M278.1,-171C278.1,-171 331.86,-171 331.86,-171 337.86,-171 343.86,-177 343.86,-183 343.86,-183 343.86,-236 343.86,-236 343.86,-242 337.86,-248 331.86,-248 331.86,-248 278.1,-248 278.1,-248 272.1,-248 266.1,-242 266.1,-236 266.1,-236 266.1,-183 266.1,-183 266.1,-177 272.1,-171 278.1,-171" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-231.4" font-family="Times,serif" font-size="14.00" fill="#f0f0f0" style="">DT</text>
|
||||
</g>
|
||||
<g id="clust4" class="cluster" data-name="clusterMerkle">
|
||||
|
||||
<path fill="#3b4b63" stroke="#e8726d" stroke-dasharray="5,2" d="M502.96,-201C502.96,-201 563.15,-201 563.15,-201 569.15,-201 575.15,-207 575.15,-213 575.15,-213 575.15,-266 575.15,-266 575.15,-272 569.15,-278 563.15,-278 563.15,-278 502.96,-278 502.96,-278 496.96,-278 490.96,-272 490.96,-266 490.96,-266 490.96,-213 490.96,-213 490.96,-207 496.96,-201 502.96,-201" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-261.4" font-family="Times,serif" font-size="14.00" fill="#f0f0f0" style="">Merkle</text>
|
||||
</g>
|
||||
<g id="clust5" class="cluster" data-name="cluster_01">
|
||||
|
||||
<polygon fill="#2e3e56" stroke="black" points="20.54,-1853 20.54,-1982 339.98,-1982 339.98,-1853 20.54,-1853" style=""/>
|
||||
<text text-anchor="middle" x="180.26" y="-1965.4" font-family="Times,serif" font-size="14.00" style="">Legend</text>
|
||||
</g>
|
||||
<!-- P2PIX.<Constructor> -->
|
||||
<g id="node1" class="node" pointer-events="visible" data-name="P2PIX.<Constructor>">
|
||||
|
||||
<ellipse fill="#ff9797" stroke="brown" stroke-width="3" cx="93.54" cy="-1713" rx="67.55" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="93.54" y="-1708.8" font-family="Times,serif" font-size="14.00" style=""><Constructor></text>
|
||||
</g>
|
||||
<!-- P2PIX.setReputation -->
|
||||
<g id="node10" class="node" pointer-events="visible" data-name="P2PIX.setReputation">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-1578" rx="64.28" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-1573.8" font-family="Times,serif" font-size="14.00" style="">setReputation</text>
|
||||
</g>
|
||||
<!-- P2PIX.<Constructor>->P2PIX.setReputation -->
|
||||
<g id="edge2" class="edge" data-name="P2PIX.<Constructor>->P2PIX.setReputation">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M109.19,-1694.04C128.87,-1669.85 166.15,-1628.34 207.08,-1605 216.35,-1599.71 226.71,-1595.41 237.12,-1591.93" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="237.86,-1595.36 246.4,-1589.09 235.81,-1588.67 237.86,-1595.36" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.setDefaultLockBlocks -->
|
||||
<g id="node11" class="node" pointer-events="visible" data-name="P2PIX.setDefaultLockBlocks">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-1740" rx="97.28" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-1735.8" font-family="Times,serif" font-size="14.00" style="">setDefaultLockBlocks</text>
|
||||
</g>
|
||||
<!-- P2PIX.<Constructor>->P2PIX.setDefaultLockBlocks -->
|
||||
<g id="edge1" class="edge" data-name="P2PIX.<Constructor>->P2PIX.setDefaultLockBlocks">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M156.25,-1720.95C172.93,-1723.11 191.38,-1725.48 209.42,-1727.81" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="208.77,-1731.25 219.13,-1729.06 209.66,-1724.31 208.77,-1731.25" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.setValidSigners -->
|
||||
<g id="node12" class="node" pointer-events="visible" data-name="P2PIX.setValidSigners">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-1686" rx="72.38" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-1681.8" font-family="Times,serif" font-size="14.00" style="">setValidSigners</text>
|
||||
</g>
|
||||
<!-- P2PIX.<Constructor>->P2PIX.setValidSigners -->
|
||||
<g id="edge3" class="edge" data-name="P2PIX.<Constructor>->P2PIX.setValidSigners">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M156.25,-1705.05C178.03,-1702.24 202.83,-1699.04 225.8,-1696.08" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="226.24,-1699.55 235.71,-1694.8 225.34,-1692.61 226.24,-1699.55" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.tokenSettings -->
|
||||
<g id="node13" class="node" pointer-events="visible" data-name="P2PIX.tokenSettings">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-1794" rx="63.72" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-1789.8" font-family="Times,serif" font-size="14.00" style="">tokenSettings</text>
|
||||
</g>
|
||||
<!-- P2PIX.<Constructor>->P2PIX.tokenSettings -->
|
||||
<g id="edge4" class="edge" data-name="P2PIX.<Constructor>->P2PIX.tokenSettings">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M126.39,-1730.14C148.57,-1741.61 179.09,-1756.48 207.08,-1767 218.13,-1771.15 230.09,-1774.99 241.72,-1778.4" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="240.66,-1781.73 251.23,-1781.09 242.57,-1775 240.66,-1781.73" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.deposit -->
|
||||
<g id="node2" class="node" pointer-events="visible" data-name="P2PIX.deposit">
|
||||
|
||||
<ellipse fill="#ff9797" stroke="#ff9797" stroke-width="3" cx="93.54" cy="-1315" rx="38.86" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="93.54" y="-1310.8" font-family="Times,serif" font-size="14.00" style="">deposit</text>
|
||||
</g>
|
||||
<!-- P2PIX.setRoot -->
|
||||
<g id="node8" class="node" pointer-events="visible" data-name="P2PIX.setRoot">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-1632" rx="40.59" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-1627.8" font-family="Times,serif" font-size="14.00" style="">setRoot</text>
|
||||
</g>
|
||||
<!-- P2PIX.deposit->P2PIX.setRoot -->
|
||||
<g id="edge11" class="edge" data-name="P2PIX.deposit->P2PIX.setRoot">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M96.19,-1334.18C101.68,-1385.96 124.04,-1529.75 207.08,-1605 219.23,-1616.01 235.51,-1622.58 251.24,-1626.48" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="250.19,-1629.83 260.7,-1628.45 251.62,-1622.98 250.19,-1629.83" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX._castToUint -->
|
||||
<g id="node19" class="node" pointer-events="visible" data-name="P2PIX._castToUint">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-1524" rx="58.55" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-1519.8" font-family="Times,serif" font-size="14.00" style="">_castToUint</text>
|
||||
</g>
|
||||
<!-- P2PIX.deposit->P2PIX._castToUint -->
|
||||
<g id="edge12" class="edge" data-name="P2PIX.deposit->P2PIX._castToUint">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M100.9,-1333.95C114.36,-1371.09 149.31,-1453.6 207.08,-1497 216.11,-1503.78 226.76,-1508.86 237.64,-1512.67" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="236.46,-1515.96 247.04,-1515.55 238.51,-1509.27 236.46,-1515.96" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX._castAddrToKey -->
|
||||
<g id="node25" class="node" pointer-events="visible" data-name="P2PIX._castAddrToKey">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-980" rx="77.58" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-975.8" font-family="Times,serif" font-size="14.00" style="">_castAddrToKey</text>
|
||||
</g>
|
||||
<!-- P2PIX.deposit->P2PIX._castAddrToKey -->
|
||||
<g id="edge6" class="edge" data-name="P2PIX.deposit->P2PIX._castAddrToKey">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M104.52,-1296.43C121.42,-1266.95 158.6,-1209.94 207.08,-1182 283.68,-1137.87 338.08,-1207.13 402.88,-1147 449.97,-1103.3 394.14,-1053.11 438.88,-1007 443.38,-1002.36 448.63,-998.5 454.29,-995.3" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="455.36,-998.67 462.89,-991.21 452.36,-992.35 455.36,-998.67" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.ERC20 -->
|
||||
<g id="node27" class="node" pointer-events="visible" data-name="P2PIX.ERC20">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-1142" rx="39.45" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-1137.8" font-family="Times,serif" font-size="14.00" style="">ERC20</text>
|
||||
</g>
|
||||
<!-- P2PIX.deposit->P2PIX.ERC20 -->
|
||||
<g id="edge5" class="edge" data-name="P2PIX.deposit->P2PIX.ERC20">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M107.41,-1296.82C126.17,-1271.88 163.59,-1227.79 207.08,-1207 286.23,-1169.17 317.6,-1202.58 402.88,-1182 419.41,-1178.01 422.7,-1174.26 438.88,-1169 453.74,-1164.17 470.08,-1159.29 484.86,-1155.04" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="485.8,-1158.41 494.47,-1152.3 483.89,-1151.67 485.8,-1158.41" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.EmptyPixTarget -->
|
||||
<g id="node28" class="node" pointer-events="visible" data-name="P2PIX.EmptyPixTarget">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-1234" rx="74.74" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-1229.8" font-family="Times,serif" font-size="14.00" style="">EmptyPixTarget</text>
|
||||
</g>
|
||||
<!-- P2PIX.deposit->P2PIX.EmptyPixTarget -->
|
||||
<g id="edge7" class="edge" data-name="P2PIX.deposit->P2PIX.EmptyPixTarget">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M120.8,-1300.78C143.25,-1289.01 176.65,-1272.44 207.08,-1261 216.73,-1257.37 227.08,-1253.99 237.29,-1250.92" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="238.09,-1254.33 246.72,-1248.18 236.14,-1247.61 238.09,-1254.33" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.TokenDenied -->
|
||||
<g id="node29" class="node" pointer-events="visible" data-name="P2PIX.TokenDenied">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-1288" rx="63.69" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-1283.8" font-family="Times,serif" font-size="14.00" style="">TokenDenied</text>
|
||||
</g>
|
||||
<!-- P2PIX.deposit->P2PIX.TokenDenied -->
|
||||
<g id="edge8" class="edge" data-name="P2PIX.deposit->P2PIX.TokenDenied">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M132.47,-1310.11C160.27,-1306.53 198.86,-1301.55 232.39,-1297.23" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="232.49,-1300.75 241.96,-1296 231.59,-1293.8 232.49,-1300.75" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.MaxBalExceeded -->
|
||||
<g id="node30" class="node" pointer-events="visible" data-name="P2PIX.MaxBalExceeded">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-1352" rx="79.85" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-1347.8" font-family="Times,serif" font-size="14.00" style="">MaxBalExceeded</text>
|
||||
</g>
|
||||
<!-- P2PIX.deposit->P2PIX.MaxBalExceeded -->
|
||||
<g id="edge9" class="edge" data-name="P2PIX.deposit->P2PIX.MaxBalExceeded">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M118.4,-1330.36C140.42,-1343.56 174.54,-1361.6 207.08,-1369 292.04,-1388.33 392.57,-1378.2 459.08,-1367.09" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="459.68,-1370.54 468.93,-1365.38 458.48,-1363.64 459.68,-1370.54" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.setReentrancyGuard -->
|
||||
<g id="node31" class="node" pointer-events="visible" data-name="P2PIX.setReentrancyGuard">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-1342" rx="89.73" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-1337.8" font-family="Times,serif" font-size="14.00" style="">setReentrancyGuard</text>
|
||||
</g>
|
||||
<!-- P2PIX.deposit->P2PIX.setReentrancyGuard -->
|
||||
<g id="edge10" class="edge" data-name="P2PIX.deposit->P2PIX.setReentrancyGuard">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M132.47,-1319.89C155.37,-1322.84 185.58,-1326.74 214.26,-1330.43" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="213.49,-1333.86 223.86,-1331.67 214.39,-1326.92 213.49,-1333.86" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.address -->
|
||||
<g id="node32" class="node" pointer-events="visible" data-name="P2PIX.address">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-582" rx="40" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-577.8" font-family="Times,serif" font-size="14.00" style="">address</text>
|
||||
</g>
|
||||
<!-- P2PIX.deposit->P2PIX.address -->
|
||||
<g id="edge14" class="edge" data-name="P2PIX.deposit->P2PIX.address">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M99.36,-1295.76C112.4,-1243.12 148.93,-1092.15 171.08,-965 181.7,-904.07 165.28,-734.59 207.08,-689 267.3,-623.34 325.02,-689.31 402.88,-646 422.93,-634.85 419.2,-620.81 438.88,-609 451.83,-601.22 467.15,-595.58 481.59,-591.53" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="482.21,-594.99 491.03,-589.12 480.47,-588.21 482.21,-594.99" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.clearReentrancyGuard -->
|
||||
<g id="node33" class="node" pointer-events="visible" data-name="P2PIX.clearReentrancyGuard">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-1416" rx="97.79" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-1411.8" font-family="Times,serif" font-size="14.00" style="">clearReentrancyGuard</text>
|
||||
</g>
|
||||
<!-- P2PIX.deposit->P2PIX.clearReentrancyGuard -->
|
||||
<g id="edge15" class="edge" data-name="P2PIX.deposit->P2PIX.clearReentrancyGuard">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M116.53,-1330.61C138.62,-1345.76 174.03,-1368.66 207.08,-1384 216.34,-1388.29 226.33,-1392.28 236.26,-1395.87" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="234.84,-1399.08 245.43,-1399.06 237.14,-1392.47 234.84,-1399.08" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.DepositAdded -->
|
||||
<g id="node34" class="node" pointer-events="visible" data-name="P2PIX.DepositAdded">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-1470" rx="66.65" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-1465.8" font-family="Times,serif" font-size="14.00" style="">DepositAdded</text>
|
||||
</g>
|
||||
<!-- P2PIX.deposit->P2PIX.DepositAdded -->
|
||||
<g id="edge16" class="edge" data-name="P2PIX.deposit->P2PIX.DepositAdded">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M105.59,-1333.26C123.42,-1361.17 161.22,-1414.21 207.08,-1443 215.51,-1448.29 224.98,-1452.56 234.61,-1456.01" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="233.37,-1459.28 243.96,-1459.02 235.51,-1452.62 233.37,-1459.28" style=""/>
|
||||
</g>
|
||||
<!-- SafeTransferLib.safeTransferFrom -->
|
||||
<g id="node58" class="node" pointer-events="visible" data-name="SafeTransferLib.safeTransferFrom">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-34" rx="80.43" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-29.8" font-family="Times,serif" font-size="14.00" style="">safeTransferFrom</text>
|
||||
</g>
|
||||
<!-- P2PIX.deposit->SafeTransferLib.safeTransferFrom -->
|
||||
<g id="edge13" class="edge" data-name="P2PIX.deposit->SafeTransferLib.safeTransferFrom">
|
||||
|
||||
<path fill="none" stroke="white" stroke-width="2" d="M99.88,-1295.85C114.26,-1243.41 153.83,-1092.91 171.08,-965 181.2,-890.02 156.72,-341.46 207.08,-285 265.82,-219.14 339.88,-313.79 402.88,-252 464.55,-191.51 380.79,-124.94 438.88,-61 442.81,-56.68 447.38,-53.03 452.35,-49.95" style=""/>
|
||||
<polygon fill="white" stroke="white" stroke-width="2" points="453.79,-53.15 461.09,-45.47 450.59,-46.92 453.79,-53.15" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.setValidState -->
|
||||
<g id="node3" class="node" pointer-events="visible" data-name="P2PIX.setValidState">
|
||||
|
||||
<ellipse fill="#ff9797" stroke="#ff9797" stroke-width="3" cx="304.98" cy="-420" rx="62.56" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-415.8" font-family="Times,serif" font-size="14.00" style="">setValidState</text>
|
||||
</g>
|
||||
<!-- P2PIX.setValidState->P2PIX._castAddrToKey -->
|
||||
<g id="edge17" class="edge" data-name="P2PIX.setValidState->P2PIX._castAddrToKey">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M366.61,-425.02C380.46,-429.07 393.76,-435.84 402.88,-447 474.2,-534.3 368,-865.34 438.88,-953 442.61,-957.62 447.08,-961.48 452.02,-964.7" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="450.32,-967.76 460.8,-969.36 453.6,-961.57 450.32,-967.76" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.setValidState->P2PIX.address -->
|
||||
<g id="edge19" class="edge" data-name="P2PIX.setValidState->P2PIX.address">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M364.79,-426.71C378.66,-430.74 392.44,-437.07 402.88,-447 439.54,-481.87 402.4,-519.94 438.88,-555 450.07,-565.76 465.29,-572.27 480.17,-576.2" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="479.03,-579.53 489.55,-578.27 480.54,-572.7 479.03,-579.53" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.ValidSet -->
|
||||
<g id="node35" class="node" pointer-events="visible" data-name="P2PIX.ValidSet">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-528" rx="44.66" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-523.8" font-family="Times,serif" font-size="14.00" style="">ValidSet</text>
|
||||
</g>
|
||||
<!-- P2PIX.setValidState->P2PIX.ValidSet -->
|
||||
<g id="edge18" class="edge" data-name="P2PIX.setValidState->P2PIX.ValidSet">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M362.34,-428.53C376.48,-432.52 391,-438.39 402.88,-447 426.23,-463.93 415.61,-483.95 438.88,-501 449.99,-509.15 463.53,-514.85 476.79,-518.83" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="475.86,-522.2 486.42,-521.37 477.64,-515.43 475.86,-522.2" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.NotInitialized -->
|
||||
<g id="node36" class="node" pointer-events="visible" data-name="P2PIX.NotInitialized">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-474" rx="64.84" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-469.8" font-family="Times,serif" font-size="14.00" style="">NotInitialized</text>
|
||||
</g>
|
||||
<!-- P2PIX.setValidState->P2PIX.NotInitialized -->
|
||||
<g id="edge20" class="edge" data-name="P2PIX.setValidState->P2PIX.NotInitialized">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M355.59,-431.85C388.96,-439.82 433.23,-450.4 469.08,-458.96" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="467.9,-462.27 478.44,-461.19 469.53,-455.47 467.9,-462.27" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.lock -->
|
||||
<g id="node4" class="node" pointer-events="visible" data-name="P2PIX.lock">
|
||||
|
||||
<ellipse fill="#ff9797" stroke="#ff9797" stroke-width="3" cx="93.54" cy="-938" rx="27.83" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="93.54" y="-933.8" font-family="Times,serif" font-size="14.00" style="">lock</text>
|
||||
</g>
|
||||
<!-- P2PIX.unlockExpired -->
|
||||
<g id="node6" class="node" pointer-events="visible" data-name="P2PIX.unlockExpired">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-790" rx="67.78" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-785.8" font-family="Times,serif" font-size="14.00" style="">unlockExpired</text>
|
||||
</g>
|
||||
<!-- P2PIX.lock->P2PIX.unlockExpired -->
|
||||
<g id="edge21" class="edge" data-name="P2PIX.lock->P2PIX.unlockExpired">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M106.78,-920.91C125.61,-895.79 164.05,-848.97 207.08,-822 216.95,-815.82 228.14,-810.7 239.32,-806.51" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="240.22,-809.9 248.52,-803.31 237.93,-803.29 240.22,-809.9" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX._addLock -->
|
||||
<g id="node16" class="node" pointer-events="visible" data-name="P2PIX._addLock">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-1120" rx="49.8" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-1115.8" font-family="Times,serif" font-size="14.00" style="">_addLock</text>
|
||||
</g>
|
||||
<!-- P2PIX.lock->P2PIX._addLock -->
|
||||
<g id="edge32" class="edge" data-name="P2PIX.lock->P2PIX._addLock">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M108.23,-954.81C126.06,-984.63 160.52,-1042.65 207.08,-1075 224.64,-1087.2 247.58,-1093.91 266.72,-1099.56" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="265.48,-1102.84 276.07,-1102.38 267.51,-1096.14 265.48,-1102.84" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.lock->P2PIX._addLock -->
|
||||
<g id="edge33" class="edge" data-name="P2PIX.lock->P2PIX._addLock">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M102.78,-956.41C118.34,-989.03 155.19,-1056.95 207.08,-1093 218.17,-1100.7 231.39,-1106.22 244.45,-1110.16" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="243.36,-1113.49 253.93,-1112.7 245.17,-1106.73 243.36,-1113.49" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.lock->P2PIX._addLock -->
|
||||
<g id="edge37" class="edge" data-name="P2PIX.lock->P2PIX._addLock">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M99.12,-957.03C111.86,-994.62 150.55,-1071.72 207.08,-1111 219.84,-1119.86 235.43,-1125.83 250.34,-1129.08" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="249.76,-1132.53 260.2,-1130.74 250.92,-1125.63 249.76,-1132.53" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.merkleVerify -->
|
||||
<g id="node17" class="node" pointer-events="visible" data-name="P2PIX.merkleVerify">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-602" rx="63.1" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-597.8" font-family="Times,serif" font-size="14.00" style="">merkleVerify</text>
|
||||
</g>
|
||||
<!-- P2PIX.lock->P2PIX.merkleVerify -->
|
||||
<g id="edge31" class="edge" data-name="P2PIX.lock->P2PIX.merkleVerify">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M96.01,-918.9C101.1,-865.89 122.65,-715.48 207.08,-634 215.28,-626.09 225.47,-620.13 236.14,-615.65" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="237.28,-618.96 245.46,-612.23 234.87,-612.39 237.28,-618.96" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX._limiter -->
|
||||
<g id="node18" class="node" pointer-events="visible" data-name="P2PIX._limiter">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-1066" rx="41.72" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-1061.8" font-family="Times,serif" font-size="14.00" style="">_limiter</text>
|
||||
</g>
|
||||
<!-- P2PIX.lock->P2PIX._limiter -->
|
||||
<g id="edge35" class="edge" data-name="P2PIX.lock->P2PIX._limiter">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M109.45,-954.13C129.71,-975.19 167.92,-1011.96 207.08,-1034 221.7,-1042.23 238.76,-1048.75 254.46,-1053.7" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="253.2,-1056.97 263.78,-1056.47 255.19,-1050.26 253.2,-1056.97" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.getBalance -->
|
||||
<g id="node21" class="node" pointer-events="visible" data-name="P2PIX.getBalance">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-690" rx="53.86" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-685.8" font-family="Times,serif" font-size="14.00" style="">getBalance</text>
|
||||
</g>
|
||||
<!-- P2PIX.lock->P2PIX.getBalance -->
|
||||
<g id="edge25" class="edge" data-name="P2PIX.lock->P2PIX.getBalance">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M96.39,-918.93C102.25,-870.31 125.17,-741.87 207.08,-689 289.97,-635.5 411.25,-655.56 479.8,-673.64" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="478.47,-676.91 489.04,-676.18 480.32,-670.16 478.47,-676.91" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.getValid -->
|
||||
<g id="node22" class="node" pointer-events="visible" data-name="P2PIX.getValid">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-548" rx="44.08" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-543.8" font-family="Times,serif" font-size="14.00" style="">getValid</text>
|
||||
</g>
|
||||
<!-- P2PIX.lock->P2PIX.getValid -->
|
||||
<g id="edge23" class="edge" data-name="P2PIX.lock->P2PIX.getValid">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M94.47,-918.58C95.36,-858.32 106.52,-672.7 207.08,-575 218.14,-564.26 233.09,-557.71 247.94,-553.75" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="248.35,-557.24 257.35,-551.65 246.83,-550.41 248.35,-557.24" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.lock->P2PIX._castAddrToKey -->
|
||||
<g id="edge27" class="edge" data-name="P2PIX.lock->P2PIX._castAddrToKey">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M114.29,-951.51C135.19,-969.13 170.2,-998.11 207.08,-1010 289.9,-1036.71 316.98,-1023.94 402.88,-1010 419.52,-1007.3 422.77,-1003.01 438.88,-998 443.58,-996.53 448.43,-995.05 453.32,-993.59" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="454.02,-997.03 462.63,-990.86 452.05,-990.31 454.02,-997.03" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.lock->P2PIX._castAddrToKey -->
|
||||
<g id="edge34" class="edge" data-name="P2PIX.lock->P2PIX._castAddrToKey">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M105.62,-955.32C124.37,-977.73 164.47,-1014.26 207.08,-1028 289.9,-1054.71 316.98,-1041.94 402.88,-1028 419.52,-1025.3 422.77,-1021.01 438.88,-1016 454.2,-1011.23 471.03,-1006.27 486.12,-1001.45" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="487.03,-1004.84 495.44,-998.4 484.85,-998.19 487.03,-1004.84" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.lock->P2PIX.ERC20 -->
|
||||
<g id="edge22" class="edge" data-name="P2PIX.lock->P2PIX.ERC20">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M109.86,-922.01C129.99,-902.28 167.45,-869.78 207.08,-857 289.9,-830.29 337.23,-799.88 402.88,-857 490.22,-933 363.09,-1027.48 438.88,-1115 449.21,-1126.94 464.47,-1133.75 479.67,-1137.59" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="478.84,-1141 489.34,-1139.57 480.24,-1134.14 478.84,-1141" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.lock->P2PIX.address -->
|
||||
<g id="edge30" class="edge" data-name="P2PIX.lock->P2PIX.address">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M95.74,-918.93C100.11,-866.86 119.95,-721.66 207.08,-654 276.37,-600.2 319.52,-656.35 402.88,-629 420.27,-623.29 421.98,-616.04 438.88,-609 453.07,-603.09 468.98,-597.96 483.59,-593.81" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="484.37,-597.23 493.09,-591.22 482.52,-590.47 484.37,-597.23" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.InvalidDeposit -->
|
||||
<g id="node37" class="node" pointer-events="visible" data-name="P2PIX.InvalidDeposit">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-884" rx="68.36" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-879.8" font-family="Times,serif" font-size="14.00" style="">InvalidDeposit</text>
|
||||
</g>
|
||||
<!-- P2PIX.lock->P2PIX.InvalidDeposit -->
|
||||
<g id="edge24" class="edge" data-name="P2PIX.lock->P2PIX.InvalidDeposit">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M120.64,-931.27C150.59,-923.55 200.75,-910.62 241.04,-900.23" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="241.73,-903.67 250.53,-897.78 239.98,-896.89 241.73,-903.67" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.NotEnoughTokens -->
|
||||
<g id="node38" class="node" pointer-events="visible" data-name="P2PIX.NotEnoughTokens">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-938" rx="83.98" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-933.8" font-family="Times,serif" font-size="14.00" style="">NotEnoughTokens</text>
|
||||
</g>
|
||||
<!-- P2PIX.lock->P2PIX.NotEnoughTokens -->
|
||||
<g id="edge26" class="edge" data-name="P2PIX.lock->P2PIX.NotEnoughTokens">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M122.79,-938C144.67,-938 176.35,-938 207.12,-938" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="206.73,-941.5 216.73,-938 206.73,-934.5 206.73,-941.5" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.NotExpired -->
|
||||
<g id="node39" class="node" pointer-events="visible" data-name="P2PIX.NotExpired">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="740.22" cy="-1187" rx="56.18" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="740.22" y="-1182.8" font-family="Times,serif" font-size="14.00" style="">NotExpired</text>
|
||||
</g>
|
||||
<!-- P2PIX.lock->P2PIX.NotExpired -->
|
||||
<g id="edge28" class="edge" data-name="P2PIX.lock->P2PIX.NotExpired">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M99.45,-957.04C111.01,-998.03 143.84,-1095.11 207.08,-1147 277.44,-1204.73 333.06,-1148.61 402.88,-1207 429.71,-1229.45 409.01,-1258.78 438.88,-1277 510.34,-1320.61 548.27,-1304.8 627.23,-1277 662.12,-1264.72 694.17,-1236.47 714.96,-1214.87" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="717.37,-1217.41 721.63,-1207.71 712.25,-1212.64 717.37,-1217.41" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.AmountNotAllowed -->
|
||||
<g id="node40" class="node" pointer-events="visible" data-name="P2PIX.AmountNotAllowed">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-992" rx="90.37" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-987.8" font-family="Times,serif" font-size="14.00" style="">AmountNotAllowed</text>
|
||||
</g>
|
||||
<!-- P2PIX.lock->P2PIX.AmountNotAllowed -->
|
||||
<g id="edge36" class="edge" data-name="P2PIX.lock->P2PIX.AmountNotAllowed">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M120.64,-944.73C148.78,-951.99 194.77,-963.84 233.64,-973.87" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="232.76,-977.25 243.32,-976.36 234.51,-970.47 232.76,-977.25" style=""/>
|
||||
</g>
|
||||
<!-- DT.Lock -->
|
||||
<g id="node61" class="node" pointer-events="visible" data-name="DT.Lock">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-197" rx="30.76" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-192.8" font-family="Times,serif" font-size="14.00" style="">Lock</text>
|
||||
</g>
|
||||
<!-- P2PIX.lock->DT.Lock -->
|
||||
<g id="edge29" class="edge" data-name="P2PIX.lock->DT.Lock">
|
||||
|
||||
<path fill="none" stroke="white" stroke-width="2" d="M98.9,-919.02C111.55,-863.46 148.76,-696.27 171.08,-556 181.77,-488.82 169.45,-308.67 207.08,-252 220.44,-231.89 243.8,-218.31 264.24,-209.68" style=""/>
|
||||
<polygon fill="white" stroke="white" stroke-width="2" points="265.28,-213.03 273.33,-206.15 262.74,-206.51 265.28,-213.03" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.release -->
|
||||
<g id="node5" class="node" pointer-events="visible" data-name="P2PIX.release">
|
||||
|
||||
<ellipse fill="#ff9797" stroke="#ff9797" stroke-width="3" cx="304.98" cy="-716" rx="37.68" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-711.8" font-family="Times,serif" font-size="14.00" style="">release</text>
|
||||
</g>
|
||||
<!-- P2PIX.release->P2PIX._castAddrToKey -->
|
||||
<g id="edge41" class="edge" data-name="P2PIX.release->P2PIX._castAddrToKey">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M321.74,-698.53C343.46,-690.99 382.25,-697.14 402.88,-721 463.37,-790.98 377.1,-857.15 438.88,-926 454.8,-943.75 481.62,-950.13 502.41,-956.85" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="500.98,-960.05 511.57,-960.16 503.35,-953.47 500.98,-960.05" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.release->P2PIX._castAddrToKey -->
|
||||
<g id="edge44" class="edge" data-name="P2PIX.release->P2PIX._castAddrToKey">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M342.83,-711.2C363.44,-713.72 387.93,-721.71 402.88,-739 463.37,-808.98 377.1,-875.15 438.88,-944 446.07,-952.02 455.49,-957.72 465.57,-961.89" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="464.16,-965.11 474.76,-965.14 466.49,-958.51 464.16,-965.11" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.release->P2PIX._castAddrToKey -->
|
||||
<g id="edge45" class="edge" data-name="P2PIX.release->P2PIX._castAddrToKey">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M338.57,-725.93C359.98,-730.65 386.89,-738.5 402.88,-757 463.37,-826.98 377.1,-893.15 438.88,-962 440.96,-964.33 443.24,-966.46 445.66,-968.41" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="443.55,-971.21 453.84,-973.76 447.39,-965.35 443.55,-971.21" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.release->P2PIX._castAddrToKey -->
|
||||
<g id="edge46" class="edge" data-name="P2PIX.release->P2PIX._castAddrToKey">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M320.66,-733.84C342.15,-744.79 381.91,-750.74 402.88,-775 463.37,-844.98 377.1,-911.15 438.88,-980 454.75,-997.69 481.43,-1004.08 502.18,-1001.73" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="502.82,-1005.18 511.83,-999.61 501.31,-998.34 502.82,-1005.18" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.release->P2PIX.ERC20 -->
|
||||
<g id="edge43" class="edge" data-name="P2PIX.release->P2PIX.ERC20">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M340.76,-723.71C362.25,-730.38 388.41,-742.32 402.88,-763 493.04,-891.85 338.13,-994.25 438.88,-1115 449.08,-1127.22 464.45,-1134.1 479.78,-1137.92" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="479.08,-1141.34 489.57,-1139.86 480.44,-1134.48 479.08,-1141.34" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.AlreadyReleased -->
|
||||
<g id="node41" class="node" pointer-events="visible" data-name="P2PIX.AlreadyReleased">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="740.22" cy="-880" rx="76.99" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="740.22" y="-875.8" font-family="Times,serif" font-size="14.00" style="">AlreadyReleased</text>
|
||||
</g>
|
||||
<!-- P2PIX.release->P2PIX.AlreadyReleased -->
|
||||
<g id="edge38" class="edge" data-name="P2PIX.release->P2PIX.AlreadyReleased">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M343.91,-716.75C423.52,-718.57 602.73,-724.06 627.23,-737 673.8,-761.59 707.27,-814.95 724.91,-849.08" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="721.75,-850.59 729.34,-857.98 728.02,-847.47 721.75,-850.59" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.LockExpired -->
|
||||
<g id="node42" class="node" pointer-events="visible" data-name="P2PIX.LockExpired">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-926" rx="61.4" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-921.8" font-family="Times,serif" font-size="14.00" style="">LockExpired</text>
|
||||
</g>
|
||||
<!-- P2PIX.release->P2PIX.LockExpired -->
|
||||
<g id="edge39" class="edge" data-name="P2PIX.release->P2PIX.LockExpired">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M343.4,-719.56C363.69,-723.42 387.66,-731.43 402.88,-748 449.55,-798.81 391.28,-849.06 438.88,-899 445.35,-905.79 453.41,-910.9 462.07,-914.75" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="460.72,-917.98 471.32,-918.19 463.16,-911.42 460.72,-917.98" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.TxAlreadyUsed -->
|
||||
<g id="node43" class="node" pointer-events="visible" data-name="P2PIX.TxAlreadyUsed">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-764" rx="72.93" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-759.8" font-family="Times,serif" font-size="14.00" style="">TxAlreadyUsed</text>
|
||||
</g>
|
||||
<!-- P2PIX.release->P2PIX.TxAlreadyUsed -->
|
||||
<g id="edge40" class="edge" data-name="P2PIX.release->P2PIX.TxAlreadyUsed">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M340.81,-723.39C373.18,-730.27 422.33,-740.7 462.7,-749.27" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="461.72,-752.64 472.23,-751.3 463.17,-745.8 461.72,-752.64" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.InvalidSigner -->
|
||||
<g id="node44" class="node" pointer-events="visible" data-name="P2PIX.InvalidSigner">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-818" rx="63.71" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-813.8" font-family="Times,serif" font-size="14.00" style="">InvalidSigner</text>
|
||||
</g>
|
||||
<!-- P2PIX.release->P2PIX.InvalidSigner -->
|
||||
<g id="edge42" class="edge" data-name="P2PIX.release->P2PIX.InvalidSigner">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M341.28,-722.68C360.65,-727.51 384.41,-735.46 402.88,-748 423.5,-762 418,-777.38 438.88,-791 446.92,-796.25 456,-800.49 465.26,-803.93" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="464,-807.2 474.59,-807.04 466.21,-800.56 464,-807.2" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.LockReleased -->
|
||||
<g id="node45" class="node" pointer-events="visible" data-name="P2PIX.LockReleased">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-872" rx="65.97" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-867.8" font-family="Times,serif" font-size="14.00" style="">LockReleased</text>
|
||||
</g>
|
||||
<!-- P2PIX.release->P2PIX.LockReleased -->
|
||||
<g id="edge51" class="edge" data-name="P2PIX.release->P2PIX.LockReleased">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M343.13,-720.39C363.08,-724.51 386.81,-732.51 402.88,-748 435.98,-779.92 405.19,-813.7 438.88,-845 445.18,-850.85 452.67,-855.45 460.63,-859.05" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="459.13,-862.22 469.72,-862.56 461.65,-855.69 459.13,-862.22" style=""/>
|
||||
</g>
|
||||
<!-- SafeTransferLib.safeTransfer -->
|
||||
<g id="node59" class="node" pointer-events="visible" data-name="SafeTransferLib.safeTransfer">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-142" rx="59.08" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-137.8" font-family="Times,serif" font-size="14.00" style="">safeTransfer</text>
|
||||
</g>
|
||||
<!-- P2PIX.release->SafeTransferLib.safeTransfer -->
|
||||
<g id="edge47" class="edge" data-name="P2PIX.release->SafeTransferLib.safeTransfer">
|
||||
|
||||
<path fill="none" stroke="white" stroke-width="2" d="M314.68,-697.38C334.45,-673.12 382.66,-642.7 402.88,-602 445.74,-515.73 387.68,-251.6 438.88,-170 444.83,-160.51 453.07,-152.45 462.21,-146.02" style=""/>
|
||||
<polygon fill="white" stroke="white" stroke-width="2" points="463.99,-149.03 470.68,-140.82 460.33,-143.07 463.99,-149.03" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.release->SafeTransferLib.safeTransfer -->
|
||||
<g id="edge48" class="edge" data-name="P2PIX.release->SafeTransferLib.safeTransfer">
|
||||
|
||||
<path fill="none" stroke="white" stroke-width="2" d="M324.44,-699.32C347.34,-682.44 385.47,-655.03 402.88,-620 445.74,-533.73 387.68,-269.6 438.88,-188 446.52,-175.82 457.93,-166 470.16,-158.47" style=""/>
|
||||
<polygon fill="white" stroke="white" stroke-width="2" points="471.83,-161.55 478.89,-153.65 468.45,-155.42 471.83,-161.55" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.release->SafeTransferLib.safeTransfer -->
|
||||
<g id="edge49" class="edge" data-name="P2PIX.release->SafeTransferLib.safeTransfer">
|
||||
|
||||
<path fill="none" stroke="white" stroke-width="2" d="M336.61,-705.04C359.14,-691.37 388.29,-667.36 402.88,-638 445.74,-551.73 387.68,-287.6 438.88,-206 450.78,-187.03 471.81,-173.79 490.89,-164.16" style=""/>
|
||||
<polygon fill="white" stroke="white" stroke-width="2" points="492.19,-167.42 499.68,-159.93 489.15,-161.11 492.19,-167.42" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.release->SafeTransferLib.safeTransfer -->
|
||||
<g id="edge50" class="edge" data-name="P2PIX.release->SafeTransferLib.safeTransfer">
|
||||
|
||||
<path fill="none" stroke="white" stroke-width="2" d="M343.79,-716.11C365.02,-704.34 389.8,-682.32 402.88,-656 445.74,-569.73 387.68,-305.6 438.88,-224 455.03,-198.26 487.98,-183.08 510.05,-168.59" style=""/>
|
||||
<polygon fill="white" stroke="white" stroke-width="2" points="511.98,-171.51 518,-162.8 507.86,-165.85 511.98,-171.51" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX._notExpired -->
|
||||
<g id="node15" class="node" pointer-events="visible" data-name="P2PIX._notExpired">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-1088" rx="58.55" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-1083.8" font-family="Times,serif" font-size="14.00" style="">_notExpired</text>
|
||||
</g>
|
||||
<!-- P2PIX.unlockExpired->P2PIX._notExpired -->
|
||||
<g id="edge52" class="edge" data-name="P2PIX.unlockExpired->P2PIX._notExpired">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M366.44,-798.86C380.2,-803.62 393.51,-810.9 402.88,-822 472.13,-904.11 368.12,-980.18 438.88,-1061 445.59,-1068.66 454.32,-1074.21 463.76,-1078.22" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="462.53,-1081.5 473.12,-1081.51 464.85,-1074.89 462.53,-1081.5" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.unlockExpired->P2PIX._castAddrToKey -->
|
||||
<g id="edge56" class="edge" data-name="P2PIX.unlockExpired->P2PIX._castAddrToKey">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M365.3,-799.57C379.16,-804.32 392.81,-811.41 402.88,-822 444.47,-865.77 396.48,-910.01 438.88,-953 443.42,-957.6 448.69,-961.43 454.38,-964.62" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="452.46,-967.58 463,-968.69 455.45,-961.25 452.46,-967.58" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.unlockExpired->P2PIX.ERC20 -->
|
||||
<g id="edge53" class="edge" data-name="P2PIX.unlockExpired->P2PIX.ERC20">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M373.64,-792.53C384.82,-797.06 395.24,-803.69 402.88,-813 486.09,-914.44 353.8,-1006.12 438.88,-1106 450.19,-1119.28 467.6,-1126.24 484.33,-1130.4" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="483.4,-1133.79 493.92,-1132.47 484.88,-1126.94 483.4,-1133.79" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.unlockExpired->P2PIX.ERC20 -->
|
||||
<g id="edge55" class="edge" data-name="P2PIX.unlockExpired->P2PIX.ERC20">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M354.53,-803.49C372.31,-808.5 390.97,-816.48 402.88,-831 486.09,-932.44 353.8,-1024.12 438.88,-1124 449.65,-1136.65 465.95,-1143.56 481.92,-1146.76" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="481.16,-1150.18 491.55,-1148.14 482.15,-1143.25 481.16,-1150.18" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.unlockExpired->P2PIX.MaxBalExceeded -->
|
||||
<g id="edge54" class="edge" data-name="P2PIX.unlockExpired->P2PIX.MaxBalExceeded">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M343.6,-806C364.76,-817.08 389.54,-834 402.88,-857 496.89,-1019.06 350.82,-1111.63 438.88,-1277 449.92,-1297.74 469.41,-1314.8 487.71,-1327.38" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="485.75,-1330.28 496.04,-1332.79 489.56,-1324.41 485.75,-1330.28" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.LockReturned -->
|
||||
<g id="node46" class="node" pointer-events="visible" data-name="P2PIX.LockReturned">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-1034" rx="66.05" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-1029.8" font-family="Times,serif" font-size="14.00" style="">LockReturned</text>
|
||||
</g>
|
||||
<!-- P2PIX.unlockExpired->P2PIX.LockReturned -->
|
||||
<g id="edge57" class="edge" data-name="P2PIX.unlockExpired->P2PIX.LockReturned">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M366.11,-799.14C379.88,-803.9 393.28,-811.1 402.88,-822 458.24,-884.86 382.37,-945.17 438.88,-1007 444.54,-1013.19 451.52,-1018 459.1,-1021.72" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="457.58,-1024.88 468.16,-1025.43 460.23,-1018.4 457.58,-1024.88" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.withdraw -->
|
||||
<g id="node7" class="node" pointer-events="visible" data-name="P2PIX.withdraw">
|
||||
|
||||
<ellipse fill="#ff9797" stroke="#ff9797" stroke-width="3" cx="93.54" cy="-529" rx="47.52" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="93.54" y="-524.8" font-family="Times,serif" font-size="14.00" style="">withdraw</text>
|
||||
</g>
|
||||
<!-- P2PIX.withdraw->P2PIX.setValidState -->
|
||||
<g id="edge60" class="edge" data-name="P2PIX.withdraw->P2PIX.setValidState">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M133,-517.66C145.94,-512.67 159.92,-505.87 171.08,-497 192.52,-479.97 184.63,-462.67 207.08,-447 215.69,-441 225.59,-436.32 235.7,-432.69" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="236.73,-436.04 245.19,-429.67 234.6,-429.37 236.73,-436.04" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.withdraw->P2PIX.unlockExpired -->
|
||||
<g id="edge58" class="edge" data-name="P2PIX.withdraw->P2PIX.unlockExpired">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M98.6,-548.07C108.85,-591.7 139.94,-699.52 207.08,-758 215.2,-765.07 224.91,-770.58 235.02,-774.88" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="233.56,-778.07 244.15,-778.33 236.03,-771.52 233.56,-778.07" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX._decBal -->
|
||||
<g id="node20" class="node" pointer-events="visible" data-name="P2PIX._decBal">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-1196" rx="42.85" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-1191.8" font-family="Times,serif" font-size="14.00" style="">_decBal</text>
|
||||
</g>
|
||||
<!-- P2PIX.withdraw->P2PIX._decBal -->
|
||||
<g id="edge62" class="edge" data-name="P2PIX.withdraw->P2PIX._decBal">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M95.95,-548.37C100.86,-600.6 121.88,-745.25 207.08,-817 275.02,-874.21 342.85,-791.54 402.88,-857 497.21,-959.88 348.76,-1062.4 438.88,-1169 448.46,-1180.34 462.5,-1187.07 476.78,-1191.02" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="475.82,-1194.39 486.34,-1193.17 477.35,-1187.56 475.82,-1194.39" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.withdraw->P2PIX.getValid -->
|
||||
<g id="edge59" class="edge" data-name="P2PIX.withdraw->P2PIX.getValid">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M141.28,-533.24C172.79,-536.1 214.51,-539.88 247.82,-542.91" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="247.31,-546.37 257.58,-543.79 247.94,-539.4 247.31,-546.37" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.withdraw->P2PIX._castAddrToKey -->
|
||||
<g id="edge61" class="edge" data-name="P2PIX.withdraw->P2PIX._castAddrToKey">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M98.28,-548.17C107.81,-591.3 137.35,-695.88 207.08,-743 243.32,-767.49 370.66,-733.42 402.88,-763 466.19,-821.12 381.05,-889.42 438.88,-953 443.05,-957.59 447.95,-961.41 453.28,-964.6" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="451.51,-967.63 462.02,-968.95 454.62,-961.36 451.51,-967.63" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.withdraw->P2PIX.address -->
|
||||
<g id="edge65" class="edge" data-name="P2PIX.withdraw->P2PIX.address">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M140.42,-523.44C214.42,-515.2 356.54,-502.58 402.88,-521 423.33,-529.13 419.77,-544.08 438.88,-555 451.99,-562.5 467.36,-568.06 481.79,-572.12" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="480.66,-575.44 491.22,-574.55 482.41,-568.66 480.66,-575.44" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.DepositWithdrawn -->
|
||||
<g id="node47" class="node" pointer-events="visible" data-name="P2PIX.DepositWithdrawn">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="304.98" cy="-474" rx="84.54" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-469.8" font-family="Times,serif" font-size="14.00" style="">DepositWithdrawn</text>
|
||||
</g>
|
||||
<!-- P2PIX.withdraw->P2PIX.DepositWithdrawn -->
|
||||
<g id="edge64" class="edge" data-name="P2PIX.withdraw->P2PIX.DepositWithdrawn">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M134.43,-518.53C163.05,-511.01 202.33,-500.69 235.88,-491.88" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="236.71,-495.28 245.49,-489.36 234.93,-488.51 236.71,-495.28" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.withdraw->SafeTransferLib.safeTransfer -->
|
||||
<g id="edge63" class="edge" data-name="P2PIX.withdraw->SafeTransferLib.safeTransfer">
|
||||
|
||||
<path fill="none" stroke="white" stroke-width="2" d="M136.76,-520.25C149.71,-515.5 162.72,-508.19 171.08,-497 215.24,-437.91 154.1,-218.32 207.08,-167 277.54,-98.76 401.57,-111.47 474.33,-126.79" style=""/>
|
||||
<polygon fill="white" stroke="white" stroke-width="2" points="473.38,-130.17 483.9,-128.91 474.89,-123.33 473.38,-130.17" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.setRoot->P2PIX._castAddrToKey -->
|
||||
<g id="edge66" class="edge" data-name="P2PIX.setRoot->P2PIX._castAddrToKey">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M346.83,-1631.17C366.85,-1628.48 389.49,-1621.57 402.88,-1605 486.54,-1501.45 355.74,-1110.98 438.88,-1007 442.59,-1002.36 447.04,-998.49 451.97,-995.26" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="453.55,-998.38 460.72,-990.59 450.25,-992.21 453.55,-998.38" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.RootUpdated -->
|
||||
<g id="node48" class="node" pointer-events="visible" data-name="P2PIX.RootUpdated">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-1578" rx="62.56" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-1573.8" font-family="Times,serif" font-size="14.00" style="">RootUpdated</text>
|
||||
</g>
|
||||
<!-- P2PIX.setRoot->P2PIX.RootUpdated -->
|
||||
<g id="edge67" class="edge" data-name="P2PIX.setRoot->P2PIX.RootUpdated">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M342.55,-1623.26C376.91,-1615.06 429,-1602.61 469.88,-1592.85" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="470.59,-1596.28 479.5,-1590.55 468.97,-1589.47 470.59,-1596.28" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.OnlySeller -->
|
||||
<g id="node49" class="node" pointer-events="visible" data-name="P2PIX.OnlySeller">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-1632" rx="52.75" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-1627.8" font-family="Times,serif" font-size="14.00" style="">OnlySeller</text>
|
||||
</g>
|
||||
<!-- P2PIX.setRoot->P2PIX.OnlySeller -->
|
||||
<g id="edge68" class="edge" data-name="P2PIX.setRoot->P2PIX.OnlySeller">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M346.92,-1632C380.11,-1632 427.55,-1632 466.09,-1632" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="466.02,-1635.5 476.02,-1632 466.02,-1628.5 466.02,-1635.5" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.withdrawBalance -->
|
||||
<g id="node9" class="node" pointer-events="visible" data-name="P2PIX.withdrawBalance">
|
||||
|
||||
<ellipse fill="#ffbdb9" stroke="#ffbdb9" stroke-width="3" cx="304.98" cy="-312" rx="78.71" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-307.8" font-family="Times,serif" font-size="14.00" style="">withdrawBalance</text>
|
||||
</g>
|
||||
<!-- P2PIX.withdrawBalance->P2PIX.address -->
|
||||
<g id="edge69" class="edge" data-name="P2PIX.withdrawBalance->P2PIX.address">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M375.62,-320.95C385.92,-325.03 395.52,-330.82 402.88,-339 467.93,-411.39 374.2,-482.28 438.88,-555 449.28,-566.7 464.42,-573.46 479.48,-577.33" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="478.54,-580.71 489.04,-579.33 479.97,-573.86 478.54,-580.71" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.FundsWithdrawn -->
|
||||
<g id="node50" class="node" pointer-events="visible" data-name="P2PIX.FundsWithdrawn">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-312" rx="78.19" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-307.8" font-family="Times,serif" font-size="14.00" style="">FundsWithdrawn</text>
|
||||
</g>
|
||||
<!-- P2PIX.withdrawBalance->P2PIX.FundsWithdrawn -->
|
||||
<g id="edge71" class="edge" data-name="P2PIX.withdrawBalance->P2PIX.FundsWithdrawn">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M385.05,-312C402.96,-312 422.13,-312 440.52,-312" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="440.38,-315.5 450.38,-312 440.38,-308.5 440.38,-315.5" style=""/>
|
||||
</g>
|
||||
<!-- SafeTransferLib.safeTransferETH -->
|
||||
<g id="node60" class="node" pointer-events="visible" data-name="SafeTransferLib.safeTransferETH">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-88" rx="78.12" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-83.8" font-family="Times,serif" font-size="14.00" style="">safeTransferETH</text>
|
||||
</g>
|
||||
<!-- P2PIX.withdrawBalance->SafeTransferLib.safeTransferETH -->
|
||||
<g id="edge70" class="edge" data-name="P2PIX.withdrawBalance->SafeTransferLib.safeTransferETH">
|
||||
|
||||
<path fill="none" stroke="white" stroke-width="2" d="M370.46,-301.05C382.62,-296.34 394.22,-289.61 402.88,-280 453.12,-224.23 387.62,-169.83 438.88,-115 443.11,-110.47 448.05,-106.69 453.41,-103.53" style=""/>
|
||||
<polygon fill="white" stroke="white" stroke-width="2" points="454.76,-106.76 462.19,-99.21 451.68,-100.48 454.76,-106.76" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.setReputation->P2PIX.address -->
|
||||
<g id="edge73" class="edge" data-name="P2PIX.setReputation->P2PIX.address">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M368.12,-1572.81C381.51,-1568.71 394.22,-1561.96 402.88,-1551 467.81,-1468.81 374.37,-691.52 438.88,-609 448.78,-596.33 464.26,-589.36 479.77,-585.59" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="479.99,-589.11 489.15,-583.78 478.66,-582.24 479.99,-589.11" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.ReputationUpdated -->
|
||||
<g id="node51" class="node" pointer-events="visible" data-name="P2PIX.ReputationUpdated">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-1524" rx="86.26" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-1519.8" font-family="Times,serif" font-size="14.00" style="">ReputationUpdated</text>
|
||||
</g>
|
||||
<!-- P2PIX.setReputation->P2PIX.ReputationUpdated -->
|
||||
<g id="edge72" class="edge" data-name="P2PIX.setReputation->P2PIX.ReputationUpdated">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M356.43,-1565.95C387.01,-1558.64 426.51,-1549.21 460.31,-1541.14" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="461.09,-1544.55 470.01,-1538.82 459.47,-1537.74 461.09,-1544.55" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.LockBlocksUpdated -->
|
||||
<g id="node52" class="node" pointer-events="visible" data-name="P2PIX.LockBlocksUpdated">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-1740" rx="90.34" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-1735.8" font-family="Times,serif" font-size="14.00" style="">LockBlocksUpdated</text>
|
||||
</g>
|
||||
<!-- P2PIX.setDefaultLockBlocks->P2PIX.LockBlocksUpdated -->
|
||||
<g id="edge74" class="edge" data-name="P2PIX.setDefaultLockBlocks->P2PIX.LockBlocksUpdated">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M403.5,-1740C411.73,-1740 420.08,-1740 428.36,-1740" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="428.26,-1743.5 438.26,-1740 428.26,-1736.5 428.26,-1743.5" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.setValidSigners->P2PIX._castAddrToKey -->
|
||||
<g id="edge75" class="edge" data-name="P2PIX.setValidSigners->P2PIX._castAddrToKey">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M373.47,-1678.86C384.81,-1674.68 395.33,-1668.39 402.88,-1659 493.79,-1545.9 348.54,-1120.56 438.88,-1007 442.57,-1002.35 447.02,-998.47 451.94,-995.24" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="453.52,-998.36 460.69,-990.56 450.22,-992.19 453.52,-998.36" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.ValidSignersUpdated -->
|
||||
<g id="node53" class="node" pointer-events="visible" data-name="P2PIX.ValidSignersUpdated">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-1686" rx="94.35" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-1681.8" font-family="Times,serif" font-size="14.00" style="">ValidSignersUpdated</text>
|
||||
</g>
|
||||
<!-- P2PIX.setValidSigners->P2PIX.ValidSignersUpdated -->
|
||||
<g id="edge76" class="edge" data-name="P2PIX.setValidSigners->P2PIX.ValidSignersUpdated">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M378.76,-1686C393.38,-1686 409.03,-1686 424.55,-1686" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="424.5,-1689.5 434.5,-1686 424.5,-1682.5 424.5,-1689.5" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.<Receive Ether> -->
|
||||
<g id="node14" class="node" pointer-events="visible" data-name="P2PIX.<Receive Ether>">
|
||||
|
||||
<ellipse fill="#ffbdb9" stroke="brown" stroke-width="3" cx="93.54" cy="-470" rx="76.21" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="93.54" y="-465.8" font-family="Times,serif" font-size="14.00" style=""><Receive Ether></text>
|
||||
</g>
|
||||
<!-- P2PIX._notExpired->P2PIX.NotExpired -->
|
||||
<g id="edge77" class="edge" data-name="P2PIX._notExpired->P2PIX.NotExpired">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M581.93,-1099.01C596.78,-1103.18 612.97,-1108.52 627.23,-1115 655.18,-1127.71 684.28,-1146.62 705.81,-1161.87" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="703.72,-1164.67 713.88,-1167.68 707.82,-1159 703.72,-1164.67" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX._notExpired->P2PIX.AlreadyReleased -->
|
||||
<g id="edge78" class="edge" data-name="P2PIX._notExpired->P2PIX.AlreadyReleased">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M587,-1079.82C601.06,-1075.82 615.56,-1069.86 627.23,-1061 678.62,-1021.99 712.01,-951.99 728.04,-911.43" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="731.27,-912.79 731.56,-902.19 724.73,-910.29 731.27,-912.79" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX._addLock->P2PIX._decBal -->
|
||||
<g id="edge79" class="edge" data-name="P2PIX._addLock->P2PIX._decBal">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M345.5,-1131.85C363.23,-1137.47 384.29,-1144.57 402.88,-1152 419.31,-1158.56 422.33,-1162.74 438.88,-1169 452.63,-1174.2 467.83,-1178.99 481.9,-1183.05" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="480.94,-1186.42 491.51,-1185.75 482.83,-1179.68 480.94,-1186.42" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.LockAdded -->
|
||||
<g id="node54" class="node" pointer-events="visible" data-name="P2PIX.LockAdded">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-1250" rx="56.75" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-1245.8" font-family="Times,serif" font-size="14.00" style="">LockAdded</text>
|
||||
</g>
|
||||
<!-- P2PIX._addLock->P2PIX.LockAdded -->
|
||||
<g id="edge80" class="edge" data-name="P2PIX._addLock->P2PIX.LockAdded">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M352.13,-1127.47C369.58,-1132.16 388.64,-1139.76 402.88,-1152 429.7,-1175.07 411.63,-1200.43 438.88,-1223 447.17,-1229.87 457.14,-1235 467.43,-1238.82" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="466.1,-1242.06 476.69,-1241.8 468.24,-1235.4 466.1,-1242.06" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.AddressDenied -->
|
||||
<g id="node55" class="node" pointer-events="visible" data-name="P2PIX.AddressDenied">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-636" rx="70.64" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-631.8" font-family="Times,serif" font-size="14.00" style="">AddressDenied</text>
|
||||
</g>
|
||||
<!-- P2PIX.merkleVerify->P2PIX.AddressDenied -->
|
||||
<g id="edge82" class="edge" data-name="P2PIX.merkleVerify->P2PIX.AddressDenied">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M362.74,-610.54C391.47,-614.86 426.73,-620.16 457.62,-624.81" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="456.7,-628.21 467.11,-626.23 457.74,-621.28 456.7,-628.21" style=""/>
|
||||
</g>
|
||||
<!-- Merkle.verify -->
|
||||
<g id="node62" class="node" pointer-events="visible" data-name="Merkle.verify">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-227" rx="34.19" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-222.8" font-family="Times,serif" font-size="14.00" style="">verify</text>
|
||||
</g>
|
||||
<!-- P2PIX.merkleVerify->Merkle.verify -->
|
||||
<g id="edge81" class="edge" data-name="P2PIX.merkleVerify->Merkle.verify">
|
||||
|
||||
<path fill="none" stroke="white" stroke-width="2" d="M366.73,-596.5C380.4,-592.44 393.59,-585.79 402.88,-575 488.46,-475.56 366.99,-391.75 438.88,-282 450.95,-263.57 471.52,-250.48 490.27,-241.71" style=""/>
|
||||
<polygon fill="white" stroke="white" stroke-width="2" points="491.64,-244.93 499.44,-237.75 488.87,-238.5 491.64,-244.93" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.getPixTarget -->
|
||||
<g id="node23" class="node" pointer-events="visible" data-name="P2PIX.getPixTarget">
|
||||
|
||||
<ellipse fill="#ff9797" stroke="#ff9797" stroke-width="3" cx="93.54" cy="-407" rx="60.83" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="93.54" y="-402.8" font-family="Times,serif" font-size="14.00" style="">getPixTarget</text>
|
||||
</g>
|
||||
<!-- P2PIX.getBalances -->
|
||||
<g id="node24" class="node" pointer-events="visible" data-name="P2PIX.getBalances">
|
||||
|
||||
<ellipse fill="#ffbdb9" stroke="#ffbdb9" stroke-width="3" cx="304.98" cy="-366" rx="57.88" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="304.98" y="-361.8" font-family="Times,serif" font-size="14.00" style="">getBalances</text>
|
||||
</g>
|
||||
<!-- P2PIX.getBalances->P2PIX.getBalance -->
|
||||
<g id="edge87" class="edge" data-name="P2PIX.getBalances->P2PIX.getBalance">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M362.61,-370.44C377.69,-374.36 392.62,-381.21 402.88,-393 482.32,-484.35 359.9,-571.24 438.88,-663 446.3,-671.63 456.3,-677.58 466.99,-681.67" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="465.78,-684.96 476.37,-684.63 467.89,-678.28 465.78,-684.96" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.getBalances->P2PIX.address -->
|
||||
<g id="edge83" class="edge" data-name="P2PIX.getBalances->P2PIX.address">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M363.49,-362.77C378.05,-366.4 392.48,-373.04 402.88,-384 453.63,-437.52 388.4,-492.22 438.88,-546 450.72,-558.62 468.08,-565.46 484.61,-569.71" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="483.51,-573.05 494.04,-571.84 485.05,-566.22 483.51,-573.05" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.getBalances->P2PIX.address -->
|
||||
<g id="edge84" class="edge" data-name="P2PIX.getBalances->P2PIX.address">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M353.18,-377.36C370.98,-381.5 390.02,-388.44 402.88,-402 453.63,-455.52 388.4,-510.22 438.88,-564 449.86,-575.7 465.58,-582.44 480.99,-585.81" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="480.33,-589.25 490.76,-587.4 481.46,-582.34 480.33,-589.25" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.NoTokens -->
|
||||
<g id="node56" class="node" pointer-events="visible" data-name="P2PIX.NoTokens">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-366" rx="51.04" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-361.8" font-family="Times,serif" font-size="14.00" style="">NoTokens</text>
|
||||
</g>
|
||||
<!-- P2PIX.getBalances->P2PIX.NoTokens -->
|
||||
<g id="edge85" class="edge" data-name="P2PIX.getBalances->P2PIX.NoTokens">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M364.2,-366C395.96,-366 435.34,-366 467.97,-366" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="467.55,-369.5 477.55,-366 467.55,-362.5 467.55,-369.5" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX.LengthMismatch -->
|
||||
<g id="node57" class="node" pointer-events="visible" data-name="P2PIX.LengthMismatch">
|
||||
|
||||
<ellipse fill="#edad56" stroke="#edad56" stroke-width="3" cx="533.05" cy="-420" rx="77.03" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="533.05" y="-415.8" font-family="Times,serif" font-size="14.00" style="">LengthMismatch</text>
|
||||
</g>
|
||||
<!-- P2PIX.getBalances->P2PIX.LengthMismatch -->
|
||||
<g id="edge86" class="edge" data-name="P2PIX.getBalances->P2PIX.LengthMismatch">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M353.1,-377.25C385.16,-384.91 428.1,-395.17 463.89,-403.72" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="462.73,-407.04 473.27,-405.96 464.36,-400.23 462.73,-407.04" style=""/>
|
||||
</g>
|
||||
<!-- P2PIX._castKeyToAddr -->
|
||||
<g id="node26" class="node" pointer-events="visible" data-name="P2PIX._castKeyToAddr">
|
||||
|
||||
<ellipse fill="#ff9797" stroke="#ff9797" stroke-width="3" cx="93.54" cy="-335" rx="77.58" ry="18" style=""/>
|
||||
<text text-anchor="middle" x="93.54" y="-330.8" font-family="Times,serif" font-size="14.00" style="">_castKeyToAddr</text>
|
||||
</g>
|
||||
<!-- key -->
|
||||
<g id="node63" class="node" pointer-events="visible" data-name="key">
|
||||
|
||||
<polygon fill="#edad56" stroke="none" stroke-width="3" points="158.54,-1949 28.54,-1949 28.54,-1861 158.54,-1861 158.54,-1949" style=""/>
|
||||
<text text-anchor="start" x="78.18" y="-1930.4" font-family="Times,serif" font-size="14.00" style="">Internal Call</text>
|
||||
<text text-anchor="start" x="74.29" y="-1910.4" font-family="Times,serif" font-size="14.00" style="">External Call</text>
|
||||
<text text-anchor="start" x="51.74" y="-1890.4" font-family="Times,serif" font-size="14.00" style="">Defined Contract</text>
|
||||
<text text-anchor="start" x="38.14" y="-1870.4" font-family="Times,serif" font-size="14.00" style="">Undefined Contract</text>
|
||||
</g>
|
||||
<!-- key2 -->
|
||||
<g id="node64" class="node" pointer-events="visible" data-name="key2">
|
||||
|
||||
<polygon fill="#edad56" stroke="none" stroke-width="3" points="331.98,-1949 277.98,-1949 277.98,-1861 331.98,-1861 331.98,-1949" style=""/>
|
||||
<text text-anchor="start" x="294.98" y="-1930.4" font-family="Times,serif" font-size="14.00" style=""> </text>
|
||||
<text text-anchor="start" x="294.98" y="-1910.4" font-family="Times,serif" font-size="14.00" style=""> </text>
|
||||
<polygon fill="#445773" stroke="none" points="292.98,-1885 292.98,-1905 317.98,-1905 317.98,-1885 292.98,-1885" style=""/>
|
||||
<text text-anchor="start" x="294.98" y="-1890.4" font-family="Times,serif" font-size="14.00" style=""> </text>
|
||||
<polygon fill="none" stroke="#e8726d" points="294.98,-1867 294.98,-1883 315.98,-1883 315.98,-1867 294.98,-1867" style=""/>
|
||||
</g>
|
||||
<!-- key->key2 -->
|
||||
<g id="edge88" class="edge" data-name="key->key2">
|
||||
|
||||
<path fill="none" stroke="#1bc6a6" stroke-width="2" d="M151.54,-1935C209.45,-1935 227.06,-1935 279.15,-1935" style=""/>
|
||||
<polygon fill="#1bc6a6" stroke="#1bc6a6" stroke-width="2" points="278.95,-1938.5 288.95,-1935 278.95,-1931.5 278.95,-1938.5" style=""/>
|
||||
</g>
|
||||
<!-- key->key2 -->
|
||||
<g id="edge89" class="edge" data-name="key->key2">
|
||||
|
||||
<path fill="none" stroke="white" stroke-width="2" d="M151.54,-1915C209.45,-1915 227.06,-1915 279.15,-1915" style=""/>
|
||||
<polygon fill="white" stroke="white" stroke-width="2" points="278.95,-1918.5 288.95,-1915 278.95,-1911.5 278.95,-1918.5" style=""/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 66 KiB |
@ -1,89 +0,0 @@
|
||||
# Solidity API
|
||||
|
||||
## BaseUtils
|
||||
|
||||
### _setUsedTransactions
|
||||
|
||||
```solidity
|
||||
function _setUsedTransactions(bytes32 message) internal
|
||||
```
|
||||
|
||||
███ Helper FX ██████████████████████████████████████████████████████████
|
||||
|
||||
### usedTransactions
|
||||
|
||||
```solidity
|
||||
function usedTransactions(bytes32 message) public view returns (bool used)
|
||||
```
|
||||
|
||||
### _signerCheck
|
||||
|
||||
```solidity
|
||||
function _signerCheck(bytes32 _message, bytes _signature) internal view
|
||||
```
|
||||
|
||||
### _merkleVerify
|
||||
|
||||
```solidity
|
||||
function _merkleVerify(bytes32[] _merkleProof, bytes32 _root, address _addr) internal pure
|
||||
```
|
||||
|
||||
### _castBool
|
||||
|
||||
```solidity
|
||||
function _castBool(bool _valid) internal pure returns (uint256 _validCasted)
|
||||
```
|
||||
|
||||
### getStr
|
||||
|
||||
```solidity
|
||||
function getStr(string str) public pure returns (bytes32 strEnc)
|
||||
```
|
||||
|
||||
### _setSellerBalance
|
||||
|
||||
```solidity
|
||||
function _setSellerBalance(address _sellerKey, contract ERC20 _erc20, uint256 _packed, bytes32 _pixTarget) internal
|
||||
```
|
||||
|
||||
### _setValidState
|
||||
|
||||
```solidity
|
||||
function _setValidState(address _sellerKey, contract ERC20 _erc20, uint256 _packed) internal
|
||||
```
|
||||
|
||||
### _addSellerBalance
|
||||
|
||||
```solidity
|
||||
function _addSellerBalance(address _sellerKey, contract ERC20 _erc20, uint256 _amount) internal
|
||||
```
|
||||
|
||||
### _decSellerBalance
|
||||
|
||||
```solidity
|
||||
function _decSellerBalance(address _sellerKey, contract ERC20 _erc20, uint256 _amount) internal
|
||||
```
|
||||
|
||||
### __sellerBalance
|
||||
|
||||
```solidity
|
||||
function __sellerBalance(address _sellerKey, contract ERC20 _erc20) internal view returns (uint256 _packed)
|
||||
```
|
||||
|
||||
### _castAddrToKey
|
||||
|
||||
```solidity
|
||||
function _castAddrToKey(address _addr) public pure returns (uint256 _key)
|
||||
```
|
||||
|
||||
Public method that handles `address`
|
||||
to `uint256` safe type casting.
|
||||
|
||||
_Function sighash: 0x4b2ae980._
|
||||
|
||||
### _castKeyToAddr
|
||||
|
||||
```solidity
|
||||
function _castKeyToAddr(uint256 _key) public pure returns (address _addr)
|
||||
```
|
||||
|
@ -1,96 +0,0 @@
|
||||
# Solidity API
|
||||
|
||||
## Constants
|
||||
|
||||
### _ROOT_UPDATED_EVENT_SIGNATURE
|
||||
|
||||
```solidity
|
||||
uint256 _ROOT_UPDATED_EVENT_SIGNATURE
|
||||
```
|
||||
|
||||
███ Constants ██████████████████████████████████████████████████████████
|
||||
|
||||
### _ALLOWED_ERC20_UPDATED_EVENT_SIGNATURE
|
||||
|
||||
```solidity
|
||||
uint256 _ALLOWED_ERC20_UPDATED_EVENT_SIGNATURE
|
||||
```
|
||||
|
||||
### _TRUSTED_FORWARDER_UPDATED_EVENT_SIGNATURE
|
||||
|
||||
```solidity
|
||||
uint256 _TRUSTED_FORWARDER_UPDATED_EVENT_SIGNATURE
|
||||
```
|
||||
|
||||
### _SELLER_ALLOWLIST_SLOT_SEED
|
||||
|
||||
```solidity
|
||||
uint256 _SELLER_ALLOWLIST_SLOT_SEED
|
||||
```
|
||||
|
||||
_Seller casted to key => Seller's allowlist merkleroot.
|
||||
mapping(uint256 => bytes32) public sellerAllowList;_
|
||||
|
||||
### _ALLOWED_ERC20_SLOT_SEED
|
||||
|
||||
```solidity
|
||||
uint256 _ALLOWED_ERC20_SLOT_SEED
|
||||
```
|
||||
|
||||
_Tokens allowed to serve as the underlying amount of a deposit.
|
||||
mapping(ERC20 => bool) public allowedERC20s;_
|
||||
|
||||
### _SELLER_BALANCE_SLOT_SEED
|
||||
|
||||
```solidity
|
||||
uint256 _SELLER_BALANCE_SLOT_SEED
|
||||
```
|
||||
|
||||
_Value in custom storage slot given by:
|
||||
mstore(0x20, token)
|
||||
mstore(0x0c, _SELLER_BALANCE_SLOT_SEED)
|
||||
mstore(0x00, seller)
|
||||
let value := sload(keccak256(0x0c, 0x34))._
|
||||
|
||||
### BITMASK_SB_ENTRY
|
||||
|
||||
```solidity
|
||||
uint256 BITMASK_SB_ENTRY
|
||||
```
|
||||
|
||||
_The bitmask of `sellerBalance` entry._
|
||||
|
||||
### BITPOS_VALID
|
||||
|
||||
```solidity
|
||||
uint256 BITPOS_VALID
|
||||
```
|
||||
|
||||
_The bit position of `valid` in `sellerBalance`._
|
||||
|
||||
### WAD
|
||||
|
||||
```solidity
|
||||
uint256 WAD
|
||||
```
|
||||
|
||||
_The scalar of BRZ token._
|
||||
|
||||
### MAXBALANCE_UPPERBOUND
|
||||
|
||||
```solidity
|
||||
uint256 MAXBALANCE_UPPERBOUND
|
||||
```
|
||||
|
||||
### REPUTATION_LOWERBOUND
|
||||
|
||||
```solidity
|
||||
uint256 REPUTATION_LOWERBOUND
|
||||
```
|
||||
|
||||
### LOCKAMOUNT_UPPERBOUND
|
||||
|
||||
```solidity
|
||||
uint256 LOCKAMOUNT_UPPERBOUND
|
||||
```
|
||||
|
@ -1,29 +0,0 @@
|
||||
# Solidity API
|
||||
|
||||
## DataTypes
|
||||
|
||||
### Lock
|
||||
|
||||
```solidity
|
||||
struct Lock {
|
||||
uint256 counter;
|
||||
uint256 expirationBlock;
|
||||
bytes32 pixTarget;
|
||||
uint80 amount;
|
||||
contract ERC20 token;
|
||||
address buyerAddress;
|
||||
address seller;
|
||||
}
|
||||
```
|
||||
|
||||
### LockStatus
|
||||
|
||||
```solidity
|
||||
enum LockStatus {
|
||||
Inexistent,
|
||||
Active,
|
||||
Expired,
|
||||
Released
|
||||
}
|
||||
```
|
||||
|
@ -1,278 +0,0 @@
|
||||
# Solidity API
|
||||
|
||||
## EventAndErrors
|
||||
|
||||
### DepositAdded
|
||||
|
||||
```solidity
|
||||
event DepositAdded(address seller, contract ERC20 token, uint256 amount)
|
||||
```
|
||||
|
||||
_0x63d8d7d5e63e9840ec91a12a160d27b7cfab294f6ba070b7359692acfe6b03bf_
|
||||
|
||||
### ValidSet
|
||||
|
||||
```solidity
|
||||
event ValidSet(address seller, contract ERC20 token, bool state)
|
||||
```
|
||||
|
||||
_0xca585721b6b442dc9183932f7c84dc2880efb67c4da52cc06873e78971105d49_
|
||||
|
||||
### DepositWithdrawn
|
||||
|
||||
```solidity
|
||||
event DepositWithdrawn(address seller, contract ERC20 token, uint256 amount)
|
||||
```
|
||||
|
||||
_0x2cd6435b1b961c13f55202979edd0765a809f69a539d8a477436c94c1211e43e_
|
||||
|
||||
### LockAdded
|
||||
|
||||
```solidity
|
||||
event LockAdded(address buyer, uint256 lockID, address seller, uint256 amount)
|
||||
```
|
||||
|
||||
_0x8fb3989f70bd172a37d15b41b015e48ea09d59329638377304a4198cd0c4ea65_
|
||||
|
||||
### LockReleased
|
||||
|
||||
```solidity
|
||||
event LockReleased(address buyer, uint256 lockId, uint256 amount)
|
||||
```
|
||||
|
||||
_0x364537f14276f2a0ce9905588413f96454cbb8fb2e4f5308389307c1098bede8_
|
||||
|
||||
### LockReturned
|
||||
|
||||
```solidity
|
||||
event LockReturned(address buyer, uint256 lockId)
|
||||
```
|
||||
|
||||
_0x830501e61b8b075e170b22a430e39454bdb12ed3e9620e586430b6ac00079da5_
|
||||
|
||||
### FundsWithdrawn
|
||||
|
||||
```solidity
|
||||
event FundsWithdrawn(address owner, uint256 amount)
|
||||
```
|
||||
|
||||
_0xeaff4b37086828766ad3268786972c0cd24259d4c87a80f9d3963a3c3d999b0d_
|
||||
|
||||
### RootUpdated
|
||||
|
||||
```solidity
|
||||
event RootUpdated(address seller, bytes32 merkleRoot)
|
||||
```
|
||||
|
||||
_0x0b294da292f26e55fd442b5c0164fbb9013036ff00c5cfdde0efd01c1baaf632_
|
||||
|
||||
### AllowedERC20Updated
|
||||
|
||||
```solidity
|
||||
event AllowedERC20Updated(address token, bool state)
|
||||
```
|
||||
|
||||
_0x5d6e86e5341d57a92c49934296c51542a25015c9b1782a1c2722a940131c3d9a_
|
||||
|
||||
### TrustedForwarderUpdated
|
||||
|
||||
```solidity
|
||||
event TrustedForwarderUpdated(address forwarder, bool state)
|
||||
```
|
||||
|
||||
_0xbee55516e29d3969d3cb8eb01351eb3c52d06f9e2435bd5a8bfe3647e185df92_
|
||||
|
||||
### ReputationUpdated
|
||||
|
||||
```solidity
|
||||
event ReputationUpdated(address reputation)
|
||||
```
|
||||
|
||||
_0xe127cf589a3879da0156d4a24f43b44f65cfa3570de594806b0bfa2fcf06884f_
|
||||
|
||||
### LockBlocksUpdated
|
||||
|
||||
```solidity
|
||||
event LockBlocksUpdated(uint256 blocks)
|
||||
```
|
||||
|
||||
_0x70fa43ca70216ad905ade86b9e650a691b2ce5a01980d0a81bdd8324141b8511_
|
||||
|
||||
### ValidSignersUpdated
|
||||
|
||||
```solidity
|
||||
event ValidSignersUpdated(address[] signers)
|
||||
```
|
||||
|
||||
_0x14a422d2412784a5749d03da98921fe468c98577b767851389a9f58ea5a363d7_
|
||||
|
||||
### OnlySeller
|
||||
|
||||
```solidity
|
||||
error OnlySeller()
|
||||
```
|
||||
|
||||
_Only seller could call this function.
|
||||
`msg.sender` and the seller differ.
|
||||
0x85d1f726_
|
||||
|
||||
### NotExpired
|
||||
|
||||
```solidity
|
||||
error NotExpired()
|
||||
```
|
||||
|
||||
_Lock not expired or already released.
|
||||
Another lock with same ID is not expired yet.
|
||||
0xd0404f85_
|
||||
|
||||
### LoopOverflow
|
||||
|
||||
```solidity
|
||||
error LoopOverflow()
|
||||
```
|
||||
|
||||
_Loop bounds have overflowed.
|
||||
0xdfb035c9_
|
||||
|
||||
### InvalidDeposit
|
||||
|
||||
```solidity
|
||||
error InvalidDeposit()
|
||||
```
|
||||
|
||||
_Deposit not valid anymore.
|
||||
0xb2e532de_
|
||||
|
||||
### NotEnoughTokens
|
||||
|
||||
```solidity
|
||||
error NotEnoughTokens()
|
||||
```
|
||||
|
||||
_Not enough token remaining on deposit.
|
||||
0x22bbb43c_
|
||||
|
||||
### AlreadyReleased
|
||||
|
||||
```solidity
|
||||
error AlreadyReleased()
|
||||
```
|
||||
|
||||
_Lock already released or returned.
|
||||
0x63b4904e_
|
||||
|
||||
### TxAlreadyUsed
|
||||
|
||||
```solidity
|
||||
error TxAlreadyUsed()
|
||||
```
|
||||
|
||||
_Transaction already used to unlock payment.
|
||||
0xf490a6ea_
|
||||
|
||||
### InvalidSigner
|
||||
|
||||
```solidity
|
||||
error InvalidSigner()
|
||||
```
|
||||
|
||||
_Signer is not a valid signer.
|
||||
0x815e1d64_
|
||||
|
||||
### AddressDenied
|
||||
|
||||
```solidity
|
||||
error AddressDenied()
|
||||
```
|
||||
|
||||
_Address doesn't exist in a MerkleTree.
|
||||
Address not allowed as relayer.
|
||||
0x3b8474be_
|
||||
|
||||
### LengthMismatch
|
||||
|
||||
```solidity
|
||||
error LengthMismatch()
|
||||
```
|
||||
|
||||
_Arrays' length don't match.
|
||||
0xff633a38_
|
||||
|
||||
### NoTokens
|
||||
|
||||
```solidity
|
||||
error NoTokens()
|
||||
```
|
||||
|
||||
_No tokens array provided as argument.
|
||||
0xdf957883_
|
||||
|
||||
### TokenDenied
|
||||
|
||||
```solidity
|
||||
error TokenDenied()
|
||||
```
|
||||
|
||||
_Token address not allowed to be deposited.
|
||||
0x1578328e_
|
||||
|
||||
### AmountNotAllowed
|
||||
|
||||
```solidity
|
||||
error AmountNotAllowed()
|
||||
```
|
||||
|
||||
_Wished amount to be locked exceeds the limit allowed.
|
||||
0x1c18f846_
|
||||
|
||||
### StaticCallFailed
|
||||
|
||||
```solidity
|
||||
error StaticCallFailed()
|
||||
```
|
||||
|
||||
_Reverts when success return value returns false.
|
||||
0xe10bf1cc_
|
||||
|
||||
### LockExpired
|
||||
|
||||
```solidity
|
||||
error LockExpired()
|
||||
```
|
||||
|
||||
_Reverts on an expired lock.
|
||||
0xf6fafba0_
|
||||
|
||||
### DecOverflow
|
||||
|
||||
```solidity
|
||||
error DecOverflow()
|
||||
```
|
||||
|
||||
_0xce3a3d37_
|
||||
|
||||
### MaxBalExceeded
|
||||
|
||||
```solidity
|
||||
error MaxBalExceeded()
|
||||
```
|
||||
|
||||
_0xf3fb0eb9_
|
||||
|
||||
### EmptyPixTarget
|
||||
|
||||
```solidity
|
||||
error EmptyPixTarget()
|
||||
```
|
||||
|
||||
_0x6a3bc53e_
|
||||
|
||||
### NotInitialized
|
||||
|
||||
```solidity
|
||||
error NotInitialized()
|
||||
```
|
||||
|
||||
_0x87138d5c_
|
||||
|
@ -1,98 +0,0 @@
|
||||
# Solidity API
|
||||
|
||||
## OwnerSettings
|
||||
|
||||
### reputation
|
||||
|
||||
```solidity
|
||||
contract IReputation reputation
|
||||
```
|
||||
|
||||
_List of valid Bacen signature addresses
|
||||
mapping(uint256 => bool) public validBacenSigners;
|
||||
Value in custom storage slot given by:
|
||||
let value := sload(shl(12, address))._
|
||||
|
||||
### defaultLockBlocks
|
||||
|
||||
```solidity
|
||||
uint256 defaultLockBlocks
|
||||
```
|
||||
|
||||
_Default blocks that lock will hold tokens._
|
||||
|
||||
### constructor
|
||||
|
||||
```solidity
|
||||
constructor(uint256 defaultBlocks, address[] validSigners, address _reputation, contract ERC20[] tokens, bool[] tokenStates) internal
|
||||
```
|
||||
|
||||
███ Constructor ████████████████████████████████████████████████████████
|
||||
|
||||
### setTrustedFowarders
|
||||
|
||||
```solidity
|
||||
function setTrustedFowarders(address[] forwarders, bool[] states) external
|
||||
```
|
||||
|
||||
███ Owner Only █████████████████████████████████████████████████████████
|
||||
|
||||
### withdrawBalance
|
||||
|
||||
```solidity
|
||||
function withdrawBalance() external
|
||||
```
|
||||
|
||||
_Contract's underlying balance withdraw method.
|
||||
Function sighash: 0x5fd8c710._
|
||||
|
||||
### setReputation
|
||||
|
||||
```solidity
|
||||
function setReputation(contract IReputation _reputation) public
|
||||
```
|
||||
|
||||
### setDefaultLockBlocks
|
||||
|
||||
```solidity
|
||||
function setDefaultLockBlocks(uint256 _blocks) public
|
||||
```
|
||||
|
||||
### setValidSigners
|
||||
|
||||
```solidity
|
||||
function setValidSigners(address[] _validSigners) public
|
||||
```
|
||||
|
||||
### tokenSettings
|
||||
|
||||
```solidity
|
||||
function tokenSettings(contract ERC20[] _tokens, bool[] _states) public
|
||||
```
|
||||
|
||||
### validBacenSigners
|
||||
|
||||
```solidity
|
||||
function validBacenSigners(uint256 signer) public view returns (bool valid)
|
||||
```
|
||||
|
||||
███ View FX ████████████████████████████████████████████████████████████
|
||||
|
||||
### sellerAllowList
|
||||
|
||||
```solidity
|
||||
function sellerAllowList(address sellerKey) public view returns (bytes32 root)
|
||||
```
|
||||
|
||||
### allowedERC20s
|
||||
|
||||
```solidity
|
||||
function allowedERC20s(contract ERC20 erc20) public view returns (bool state)
|
||||
```
|
||||
|
||||
### _limiter
|
||||
|
||||
```solidity
|
||||
function _limiter(uint256 _userCredit) internal view returns (uint256 _spendLimit)
|
||||
```
|
||||
|
@ -1,42 +0,0 @@
|
||||
# Solidity API
|
||||
|
||||
## Owned
|
||||
|
||||
Simple single owner authorization mixin.
|
||||
|
||||
### Unauthorized
|
||||
|
||||
```solidity
|
||||
error Unauthorized()
|
||||
```
|
||||
|
||||
### OwnerUpdated
|
||||
|
||||
```solidity
|
||||
event OwnerUpdated(address user, address newOwner)
|
||||
```
|
||||
|
||||
### owner
|
||||
|
||||
```solidity
|
||||
address owner
|
||||
```
|
||||
|
||||
### onlyOwner
|
||||
|
||||
```solidity
|
||||
modifier onlyOwner()
|
||||
```
|
||||
|
||||
### constructor
|
||||
|
||||
```solidity
|
||||
constructor(address _owner) internal
|
||||
```
|
||||
|
||||
### setOwner
|
||||
|
||||
```solidity
|
||||
function setOwner(address newOwner) public virtual
|
||||
```
|
||||
|
@ -1,10 +0,0 @@
|
||||
# Solidity API
|
||||
|
||||
## IReputation
|
||||
|
||||
### limiter
|
||||
|
||||
```solidity
|
||||
function limiter(uint256 _userCredit) external pure returns (uint256 _spendLimit)
|
||||
```
|
||||
|
@ -1,53 +0,0 @@
|
||||
# Solidity API
|
||||
|
||||
## Context
|
||||
|
||||
_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._
|
||||
|
||||
### _msgSender
|
||||
|
||||
```solidity
|
||||
function _msgSender() internal view virtual returns (address)
|
||||
```
|
||||
|
||||
### _msgData
|
||||
|
||||
```solidity
|
||||
function _msgData() internal view virtual returns (bytes)
|
||||
```
|
||||
|
||||
## ERC2771Context
|
||||
|
||||
_Context variant with ERC2771 support._
|
||||
|
||||
### trustedForwarders
|
||||
|
||||
```solidity
|
||||
mapping(address => bool) trustedForwarders
|
||||
```
|
||||
|
||||
### _msgSender
|
||||
|
||||
```solidity
|
||||
function _msgSender() internal view virtual returns (address sender)
|
||||
```
|
||||
|
||||
### isTrustedForwarder
|
||||
|
||||
```solidity
|
||||
function isTrustedForwarder(address forwarder) public view virtual returns (bool)
|
||||
```
|
||||
|
||||
### _msgData
|
||||
|
||||
```solidity
|
||||
function _msgData() internal view virtual returns (bytes)
|
||||
```
|
||||
|
@ -1,224 +0,0 @@
|
||||
# MockToken
|
||||
|
||||
## Methods
|
||||
|
||||
### DOMAIN_SEPARATOR
|
||||
|
||||
```solidity
|
||||
function DOMAIN_SEPARATOR() external view returns (bytes32)
|
||||
```
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ------- | ----------- |
|
||||
| \_0 | bytes32 | undefined |
|
||||
|
||||
### allowance
|
||||
|
||||
```solidity
|
||||
function allowance(address, address) external view returns (uint256)
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ------- | ----------- |
|
||||
| \_0 | address | undefined |
|
||||
| \_1 | address | undefined |
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ------- | ----------- |
|
||||
| \_0 | uint256 | undefined |
|
||||
|
||||
### approve
|
||||
|
||||
```solidity
|
||||
function approve(address spender, uint256 amount) external nonpayable returns (bool)
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------- | ------- | ----------- |
|
||||
| spender | address | undefined |
|
||||
| amount | uint256 | undefined |
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| \_0 | bool | undefined |
|
||||
|
||||
### balanceOf
|
||||
|
||||
```solidity
|
||||
function balanceOf(address) external view returns (uint256)
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ------- | ----------- |
|
||||
| \_0 | address | undefined |
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ------- | ----------- |
|
||||
| \_0 | uint256 | undefined |
|
||||
|
||||
### decimals
|
||||
|
||||
```solidity
|
||||
function decimals() external view returns (uint8)
|
||||
```
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ----- | ----------- |
|
||||
| \_0 | uint8 | undefined |
|
||||
|
||||
### name
|
||||
|
||||
```solidity
|
||||
function name() external view returns (string)
|
||||
```
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ------ | ----------- |
|
||||
| \_0 | string | undefined |
|
||||
|
||||
### nonces
|
||||
|
||||
```solidity
|
||||
function nonces(address) external view returns (uint256)
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ------- | ----------- |
|
||||
| \_0 | address | undefined |
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ------- | ----------- |
|
||||
| \_0 | uint256 | undefined |
|
||||
|
||||
### permit
|
||||
|
||||
```solidity
|
||||
function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external nonpayable
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| -------- | ------- | ----------- |
|
||||
| owner | address | undefined |
|
||||
| spender | address | undefined |
|
||||
| value | uint256 | undefined |
|
||||
| deadline | uint256 | undefined |
|
||||
| v | uint8 | undefined |
|
||||
| r | bytes32 | undefined |
|
||||
| s | bytes32 | undefined |
|
||||
|
||||
### symbol
|
||||
|
||||
```solidity
|
||||
function symbol() external view returns (string)
|
||||
```
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ------ | ----------- |
|
||||
| \_0 | string | undefined |
|
||||
|
||||
### totalSupply
|
||||
|
||||
```solidity
|
||||
function totalSupply() external view returns (uint256)
|
||||
```
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ------- | ----------- |
|
||||
| \_0 | uint256 | undefined |
|
||||
|
||||
### transfer
|
||||
|
||||
```solidity
|
||||
function transfer(address to, uint256 amount) external nonpayable returns (bool)
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------ | ------- | ----------- |
|
||||
| to | address | undefined |
|
||||
| amount | uint256 | undefined |
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| \_0 | bool | undefined |
|
||||
|
||||
### transferFrom
|
||||
|
||||
```solidity
|
||||
function transferFrom(address from, address to, uint256 amount) external nonpayable returns (bool)
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------ | ------- | ----------- |
|
||||
| from | address | undefined |
|
||||
| to | address | undefined |
|
||||
| amount | uint256 | undefined |
|
||||
|
||||
#### Returns
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| \_0 | bool | undefined |
|
||||
|
||||
## Events
|
||||
|
||||
### Approval
|
||||
|
||||
```solidity
|
||||
event Approval(address indexed owner, address indexed spender, uint256 amount)
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| ----------------- | ------- | ----------- |
|
||||
| owner `indexed` | address | undefined |
|
||||
| spender `indexed` | address | undefined |
|
||||
| amount | uint256 | undefined |
|
||||
|
||||
### Transfer
|
||||
|
||||
```solidity
|
||||
event Transfer(address indexed from, address indexed to, uint256 amount)
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| -------------- | ------- | ----------- |
|
||||
| from `indexed` | address | undefined |
|
||||
| to `indexed` | address | undefined |
|
||||
| amount | uint256 | undefined |
|
@ -1,16 +0,0 @@
|
||||
# Solidity API
|
||||
|
||||
## MockToken
|
||||
|
||||
### constructor
|
||||
|
||||
```solidity
|
||||
constructor(uint256 supply) public
|
||||
```
|
||||
|
||||
### mint
|
||||
|
||||
```solidity
|
||||
function mint(address[] to, uint256 value) public virtual
|
||||
```
|
||||
|
@ -1,128 +0,0 @@
|
||||
# Solidity API
|
||||
|
||||
## ERC20
|
||||
|
||||
Modern and gas efficient ERC20 + EIP-2612 implementation.
|
||||
|
||||
_Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it._
|
||||
|
||||
### Transfer
|
||||
|
||||
```solidity
|
||||
event Transfer(address from, address to, uint256 amount)
|
||||
```
|
||||
|
||||
### Approval
|
||||
|
||||
```solidity
|
||||
event Approval(address owner, address spender, uint256 amount)
|
||||
```
|
||||
|
||||
### name
|
||||
|
||||
```solidity
|
||||
string name
|
||||
```
|
||||
|
||||
### symbol
|
||||
|
||||
```solidity
|
||||
string symbol
|
||||
```
|
||||
|
||||
### decimals
|
||||
|
||||
```solidity
|
||||
uint8 decimals
|
||||
```
|
||||
|
||||
### totalSupply
|
||||
|
||||
```solidity
|
||||
uint256 totalSupply
|
||||
```
|
||||
|
||||
### balanceOf
|
||||
|
||||
```solidity
|
||||
mapping(address => uint256) balanceOf
|
||||
```
|
||||
|
||||
### allowance
|
||||
|
||||
```solidity
|
||||
mapping(address => mapping(address => uint256)) allowance
|
||||
```
|
||||
|
||||
### INITIAL_CHAIN_ID
|
||||
|
||||
```solidity
|
||||
uint256 INITIAL_CHAIN_ID
|
||||
```
|
||||
|
||||
### INITIAL_DOMAIN_SEPARATOR
|
||||
|
||||
```solidity
|
||||
bytes32 INITIAL_DOMAIN_SEPARATOR
|
||||
```
|
||||
|
||||
### nonces
|
||||
|
||||
```solidity
|
||||
mapping(address => uint256) nonces
|
||||
```
|
||||
|
||||
### constructor
|
||||
|
||||
```solidity
|
||||
constructor(string _name, string _symbol, uint8 _decimals) internal
|
||||
```
|
||||
|
||||
### approve
|
||||
|
||||
```solidity
|
||||
function approve(address spender, uint256 amount) public virtual returns (bool)
|
||||
```
|
||||
|
||||
### transfer
|
||||
|
||||
```solidity
|
||||
function transfer(address to, uint256 amount) public virtual returns (bool)
|
||||
```
|
||||
|
||||
### transferFrom
|
||||
|
||||
```solidity
|
||||
function transferFrom(address from, address to, uint256 amount) public virtual returns (bool)
|
||||
```
|
||||
|
||||
### permit
|
||||
|
||||
```solidity
|
||||
function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual
|
||||
```
|
||||
|
||||
### DOMAIN_SEPARATOR
|
||||
|
||||
```solidity
|
||||
function DOMAIN_SEPARATOR() public view virtual returns (bytes32)
|
||||
```
|
||||
|
||||
### computeDomainSeparator
|
||||
|
||||
```solidity
|
||||
function computeDomainSeparator() internal view virtual returns (bytes32)
|
||||
```
|
||||
|
||||
### _mint
|
||||
|
||||
```solidity
|
||||
function _mint(address to, uint256 amount) internal virtual
|
||||
```
|
||||
|
||||
### _burn
|
||||
|
||||
```solidity
|
||||
function _burn(address from, uint256 amount) internal virtual
|
||||
```
|
||||
|
@ -1,19 +0,0 @@
|
||||
# Counters
|
||||
|
||||
_buf0t9Modified from OpenZeppelin Contracts (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Counters.sol)_
|
||||
|
||||
> Counters
|
||||
|
||||
Provides counters that can only be incremented, decrementedor reset.
|
||||
|
||||
_Include with `using Counters for Counters.Counter;`_
|
||||
|
||||
## Errors
|
||||
|
||||
### DecOverflow
|
||||
|
||||
```solidity
|
||||
error DecOverflow()
|
||||
```
|
||||
|
||||
_0xce3a3d37_
|
@ -1,38 +0,0 @@
|
||||
# Solidity API
|
||||
|
||||
## ECDSA
|
||||
|
||||
Gas optimized ECDSA wrapper.
|
||||
|
||||
### InvalidSignature
|
||||
|
||||
```solidity
|
||||
error InvalidSignature()
|
||||
```
|
||||
|
||||
_The signature is invalid._
|
||||
|
||||
### recoverCalldata
|
||||
|
||||
```solidity
|
||||
function recoverCalldata(bytes32 hash, bytes signature) internal view returns (address result)
|
||||
```
|
||||
|
||||
_Recovers the signer's address from a message digest `hash`,
|
||||
and the `signature`.
|
||||
|
||||
This function does NOT accept EIP-2098 short form signatures.
|
||||
Use `recover(bytes32 hash, bytes32 r, bytes32 vs)` for EIP-2098
|
||||
short form signatures instead._
|
||||
|
||||
### toEthSignedMessageHash
|
||||
|
||||
```solidity
|
||||
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 result)
|
||||
```
|
||||
|
||||
_Returns an Ethereum Signed Message, created from a `hash`.
|
||||
This produces a hash corresponding to the one signed with the
|
||||
[`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign)
|
||||
JSON-RPC method as part of EIP-191._
|
||||
|
@ -1,5 +0,0 @@
|
||||
# FixedPointMathLib
|
||||
|
||||
_Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)_
|
||||
|
||||
Arithmetic library with operations for fixed-point numbers.
|
@ -1,14 +0,0 @@
|
||||
# Solidity API
|
||||
|
||||
## MerkleProofLib
|
||||
|
||||
Gas optimized verification of proof of inclusion for a leaf in a Merkle tree.
|
||||
|
||||
### verify
|
||||
|
||||
```solidity
|
||||
function verify(bytes32[] proof, bytes32 root, bytes32 leaf) internal pure returns (bool isValid)
|
||||
```
|
||||
|
||||
_Returns whether `leaf` exists in the Merkle tree with `root`, given `proof`._
|
||||
|
@ -1,50 +0,0 @@
|
||||
# Solidity API
|
||||
|
||||
## Multicall
|
||||
|
||||
Contract that batches view function calls and aggregates their results.
|
||||
|
||||
### CallFailed
|
||||
|
||||
```solidity
|
||||
error CallFailed(string reason)
|
||||
```
|
||||
|
||||
_0x_
|
||||
|
||||
### Call
|
||||
|
||||
```solidity
|
||||
struct Call {
|
||||
address target;
|
||||
bytes callData;
|
||||
}
|
||||
```
|
||||
|
||||
### Result
|
||||
|
||||
```solidity
|
||||
struct Result {
|
||||
bool success;
|
||||
bytes returnData;
|
||||
}
|
||||
```
|
||||
|
||||
### constructor
|
||||
|
||||
```solidity
|
||||
constructor() public payable
|
||||
```
|
||||
|
||||
### mtc1
|
||||
|
||||
```solidity
|
||||
function mtc1(struct Multicall.Call[] calls) external returns (uint256, bytes[])
|
||||
```
|
||||
|
||||
### mtc2
|
||||
|
||||
```solidity
|
||||
function mtc2(struct Multicall.Call[] calls) external returns (uint256, bytes32, struct Multicall.Result[])
|
||||
```
|
||||
|
@ -1,34 +0,0 @@
|
||||
# Solidity API
|
||||
|
||||
## ReentrancyGuard
|
||||
|
||||
Reentrancy protection for smart contracts.
|
||||
|
||||
### Reentrancy
|
||||
|
||||
```solidity
|
||||
error Reentrancy()
|
||||
```
|
||||
|
||||
### nonReentrant
|
||||
|
||||
```solidity
|
||||
modifier nonReentrant()
|
||||
```
|
||||
|
||||
### setReentrancyGuard
|
||||
|
||||
```solidity
|
||||
function setReentrancyGuard() internal virtual
|
||||
```
|
||||
|
||||
_Check guard sentinel value and set it._
|
||||
|
||||
### clearReentrancyGuard
|
||||
|
||||
```solidity
|
||||
function clearReentrancyGuard() internal virtual
|
||||
```
|
||||
|
||||
_Unset sentinel value._
|
||||
|
@ -1,62 +0,0 @@
|
||||
# Solidity API
|
||||
|
||||
## SafeTransferLib
|
||||
|
||||
Safe ETH and ERC20 transfer library that gracefully handles missing return values.
|
||||
|
||||
_Caution! This library won't check that a token has code, responsibility is delegated to the caller._
|
||||
|
||||
### ETHTransferFailed
|
||||
|
||||
```solidity
|
||||
error ETHTransferFailed()
|
||||
```
|
||||
|
||||
_The ETH transfer has failed._
|
||||
|
||||
### TransferFromFailed
|
||||
|
||||
```solidity
|
||||
error TransferFromFailed()
|
||||
```
|
||||
|
||||
_The ERC20 `transferFrom` has failed._
|
||||
|
||||
### TransferFailed
|
||||
|
||||
```solidity
|
||||
error TransferFailed()
|
||||
```
|
||||
|
||||
_The ERC20 `transfer` has failed._
|
||||
|
||||
### safeTransferETH
|
||||
|
||||
```solidity
|
||||
function safeTransferETH(address to, uint256 amount) internal
|
||||
```
|
||||
|
||||
_Sends `amount` (in wei) ETH to `to`.
|
||||
Reverts upon failure._
|
||||
|
||||
### safeTransferFrom
|
||||
|
||||
```solidity
|
||||
function safeTransferFrom(contract ERC20 token, address from, address to, uint256 amount) internal
|
||||
```
|
||||
|
||||
_Sends `amount` of ERC20 `token` from `from` to `to`.
|
||||
Reverts upon failure.
|
||||
|
||||
The `from` account must have at least `amount` approved for
|
||||
the current contract to manage._
|
||||
|
||||
### safeTransfer
|
||||
|
||||
```solidity
|
||||
function safeTransfer(contract ERC20 token, address to, uint256 amount) internal
|
||||
```
|
||||
|
||||
_Sends `amount` of ERC20 `token` from the current contract to `to`.
|
||||
Reverts upon failure._
|
||||
|
207
docs/p2pix.md
207
docs/p2pix.md
@ -1,207 +0,0 @@
|
||||
# Solidity API
|
||||
|
||||
## P2PIX
|
||||
|
||||
### lockCounter
|
||||
|
||||
```solidity
|
||||
uint256 lockCounter
|
||||
```
|
||||
|
||||
### mapLocks
|
||||
|
||||
```solidity
|
||||
mapping(uint256 => struct DataTypes.Lock) mapLocks
|
||||
```
|
||||
|
||||
_List of Locks._
|
||||
|
||||
### userRecord
|
||||
|
||||
```solidity
|
||||
mapping(uint256 => uint256) userRecord
|
||||
```
|
||||
|
||||
_Stores an relayer's last computed credit._
|
||||
|
||||
### constructor
|
||||
|
||||
```solidity
|
||||
constructor(uint256 defaultBlocks, address[] validSigners, address _reputation, contract ERC20[] tokens, bool[] tokenStates) public payable
|
||||
```
|
||||
|
||||
### deposit
|
||||
|
||||
```solidity
|
||||
function deposit(string pixTarget, bytes32 allowlistRoot, contract ERC20 token, uint96 amount, bool valid) public
|
||||
```
|
||||
|
||||
Creates a deposit order based on a seller's
|
||||
offer of an amount of ERC20 tokens.
|
||||
Seller needs to send his tokens to the P2PIX smart contract.
|
||||
|
||||
_Function sighash: 0x5e918943_
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| pixTarget | string | Pix key destination provided by the offer's seller. |
|
||||
| allowlistRoot | bytes32 | Optional allow list merkleRoot update `bytes32` value. as the deposit identifier. |
|
||||
| token | contract ERC20 | |
|
||||
| amount | uint96 | |
|
||||
| valid | bool | |
|
||||
|
||||
### setValidState
|
||||
|
||||
```solidity
|
||||
function setValidState(contract ERC20 token, bool state) public
|
||||
```
|
||||
|
||||
Enables seller to invalidate future
|
||||
locks made to his/her token offering order.
|
||||
This function does not affect any ongoing active locks.
|
||||
|
||||
_Function sighash: 0x6d82d9e0_
|
||||
|
||||
### lock
|
||||
|
||||
```solidity
|
||||
function lock(address seller, contract ERC20 token, uint80 amount, bytes32[] merkleProof, uint256[] expiredLocks) public returns (uint256 lockID)
|
||||
```
|
||||
|
||||
Public method designed to lock an remaining amount of
|
||||
the deposit order of a seller.
|
||||
Transaction forwarding must leave `merkleProof` empty;
|
||||
otherwise, the trustedForwarder must be previously added
|
||||
to a seller whitelist.
|
||||
This method can be performed either by:
|
||||
- An user allowed via the seller's allowlist;
|
||||
- An user with enough userRecord to lock the wished amount;
|
||||
There can only exist a lock per each `_amount` partitioned
|
||||
from the total `remaining` value.
|
||||
Locks can only be performed in valid orders.
|
||||
|
||||
_Function sighash: 0xdc43221c_
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| seller | address | |
|
||||
| token | contract ERC20 | |
|
||||
| amount | uint80 | The deposit's remaining amount wished to be locked. |
|
||||
| merkleProof | bytes32[] | Provided as a pass if the `msg.sender` is in the seller's allowlist; Left empty otherwise; |
|
||||
| expiredLocks | uint256[] | An array of identifiers to be provided so to unexpire locks using this transaction gas push. |
|
||||
|
||||
#### Return Values
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| lockID | uint256 | The lock identifier. |
|
||||
|
||||
### release
|
||||
|
||||
```solidity
|
||||
function release(uint256 lockID, bytes32 pixTimestamp, bytes signature) public
|
||||
```
|
||||
|
||||
Lock release method that liquidate lock
|
||||
orders and distributes relayer fees.
|
||||
This method can be called by any public actor
|
||||
as long the signature provided is valid.
|
||||
`relayerPremium` gets splitted equaly
|
||||
if relayer addresses differ.
|
||||
If the `msg.sender` of this method and `l.relayerAddress` are the same,
|
||||
`msg.sender` accrues both l.amount and l.relayerPremium as userRecord credit.
|
||||
In case of they differing:
|
||||
- `lock` caller gets accrued with `l.amount` as userRecord credit;
|
||||
- `release` caller gets accrued with `l.relayerPremium` as userRecord credit;
|
||||
|
||||
_Function sighash: 0x11fc7f9a_
|
||||
|
||||
### unlockExpired
|
||||
|
||||
```solidity
|
||||
function unlockExpired(uint256[] lockIDs) public
|
||||
```
|
||||
|
||||
Unlocks expired locks.
|
||||
Triggered in the callgraph by both `lock` and `withdraw` functions.
|
||||
This method can also have any public actor as its `tx.origin`.
|
||||
For each successfull unexpired lock recovered,
|
||||
`userRecord[_castAddrToKey(l.relayerAddress)]` is decreased by half of its value.
|
||||
|
||||
_Function sighash: 0xb0983d39_
|
||||
|
||||
### withdraw
|
||||
|
||||
```solidity
|
||||
function withdraw(contract ERC20 token, uint256 amount, uint256[] expiredLocks) public
|
||||
```
|
||||
|
||||
Seller's expired deposit fund sweeper.
|
||||
A seller may use this method to recover
|
||||
tokens from expired deposits.
|
||||
|
||||
_Function sighash: 0xfb8c5ef0_
|
||||
|
||||
### setRoot
|
||||
|
||||
```solidity
|
||||
function setRoot(address addr, bytes32 merkleroot) public
|
||||
```
|
||||
|
||||
### receive
|
||||
|
||||
```solidity
|
||||
receive() external payable
|
||||
```
|
||||
|
||||
### _addLock
|
||||
|
||||
```solidity
|
||||
function _addLock(uint256 _bal, struct DataTypes.Lock _l) internal
|
||||
```
|
||||
|
||||
### getBalance
|
||||
|
||||
```solidity
|
||||
function getBalance(address seller, contract ERC20 token) public view returns (uint256 bal)
|
||||
```
|
||||
|
||||
### getValid
|
||||
|
||||
```solidity
|
||||
function getValid(address seller, contract ERC20 token) public view returns (bool valid)
|
||||
```
|
||||
|
||||
### getPixTarget
|
||||
|
||||
```solidity
|
||||
function getPixTarget(address seller, contract ERC20 token) public view returns (bytes32 pixTarget)
|
||||
```
|
||||
|
||||
### getPixTargetString
|
||||
|
||||
```solidity
|
||||
function getPixTargetString(address seller, contract ERC20 token) public view returns (string pixTarget)
|
||||
```
|
||||
|
||||
### getBalances
|
||||
|
||||
```solidity
|
||||
function getBalances(address[] sellers, contract ERC20 token) external view returns (uint256[])
|
||||
```
|
||||
|
||||
### getLocksStatus
|
||||
|
||||
```solidity
|
||||
function getLocksStatus(uint256[] ids) external view returns (uint256[], enum DataTypes.LockStatus[])
|
||||
```
|
||||
|
||||
External getter that returns the status of a lockIDs array.
|
||||
Call will not revert if provided with an empty array as parameter.
|
||||
|
||||
_Function sighash: 0x49ef8448_
|
||||
|
12
hardhat.config.js
Normal file
12
hardhat.config.js
Normal file
@ -0,0 +1,12 @@
|
||||
require("@nomiclabs/hardhat-waffle");
|
||||
|
||||
/** @type import('hardhat/config').HardhatUserConfig */
|
||||
module.exports = {
|
||||
solidity: "0.8.17",
|
||||
networks: {
|
||||
hardhat: {
|
||||
blockGasLimit: 30000000,
|
||||
//hardfork: 'london'
|
||||
}
|
||||
}
|
||||
};
|
@ -1,157 +0,0 @@
|
||||
import "@nomicfoundation/hardhat-chai-matchers";
|
||||
import "@nomicfoundation/hardhat-toolbox";
|
||||
import { config as dotenvConfig } from "dotenv";
|
||||
import { HardhatUserConfig } from "hardhat/config";
|
||||
import { NetworkUserConfig } from "hardhat/types";
|
||||
import "hardhat-contract-sizer";
|
||||
import { resolve } from "path";
|
||||
import "solidity-docgen";
|
||||
|
||||
dotenvConfig({ path: resolve(__dirname, "./.env") });
|
||||
|
||||
const mnemonic: string | undefined = process.env.MNEMONIC;
|
||||
if (!mnemonic) {
|
||||
throw new Error("Please set your MNEMONIC in a .env file");
|
||||
}
|
||||
|
||||
const infuraApiKey: string | undefined =
|
||||
process.env.INFURA_API_KEY;
|
||||
if (!infuraApiKey) {
|
||||
throw new Error(
|
||||
"Please set your INFURA_API_KEY in a .env file",
|
||||
);
|
||||
}
|
||||
|
||||
const alchemyApiKey: string | undefined =
|
||||
process.env.ALCHEMY_API_KEY;
|
||||
if (!alchemyApiKey) {
|
||||
throw new Error(
|
||||
"Please set your ALCHEMY_API_KEY in a .env file",
|
||||
);
|
||||
}
|
||||
|
||||
const chainIds = {
|
||||
// "{INSERT_NAME}": {INSERT_ID},
|
||||
hardhat: 31337,
|
||||
mainnet: 1,
|
||||
sepolia: 11155111,
|
||||
goerli: 5,
|
||||
"polygon-mumbai": 80001,
|
||||
rootstock:30,
|
||||
rsktestnet:31,
|
||||
};
|
||||
|
||||
function getChainConfig(
|
||||
chain: keyof typeof chainIds,
|
||||
): NetworkUserConfig {
|
||||
let jsonRpcUrl: string;
|
||||
switch (chain) {
|
||||
case "polygon-mumbai":
|
||||
jsonRpcUrl =
|
||||
"https://polygon-mumbai.g.alchemy.com/v2/" +
|
||||
alchemyApiKey;
|
||||
break;
|
||||
case "rsktestnet":
|
||||
jsonRpcUrl = "https://public-node.testnet.rsk.co/";
|
||||
break;
|
||||
case "rootstock":
|
||||
jsonRpcUrl = "https://public-node.rsk.co/";
|
||||
break;
|
||||
case "sepolia":
|
||||
jsonRpcUrl = "https://rpc.sepolia.online";
|
||||
break
|
||||
default:
|
||||
jsonRpcUrl =
|
||||
"https://" + chain + ".infura.io/v3/" + infuraApiKey;
|
||||
}
|
||||
return {
|
||||
// Comment out for default hardhat account settings
|
||||
accounts: {
|
||||
count: 10,
|
||||
mnemonic,
|
||||
path: "m/44'/60'/0'/0",
|
||||
},
|
||||
// gasPrice: 8000000000,
|
||||
chainId: chainIds[chain],
|
||||
url: jsonRpcUrl,
|
||||
};
|
||||
}
|
||||
|
||||
const config: HardhatUserConfig = {
|
||||
defaultNetwork: "hardhat",
|
||||
etherscan: {
|
||||
apiKey: {
|
||||
mainnet: process.env.ETHERSCAN_API_KEY || "",
|
||||
rinkeby: process.env.ETHERSCAN_API_KEY || "",
|
||||
goerli: process.env.ETHERSCAN_API_KEY || "",
|
||||
polygonMumbai: process.env.POLYGONSCAN_API_KEY || "",
|
||||
},
|
||||
},
|
||||
gasReporter: {
|
||||
enabled: !!(
|
||||
process.env.REPORT_GAS &&
|
||||
process.env.REPORT_GAS != "false"
|
||||
),
|
||||
showTimeSpent: true,
|
||||
showMethodSig: true,
|
||||
token: "ETH",
|
||||
currency: "USD",
|
||||
// gasPriceApi: process.env.GASPRICE_API_ENDPOINT,
|
||||
coinmarketcap: process.env.COINMARKETCAP_API_KEY,
|
||||
excludeContracts: [],
|
||||
src: "./contracts",
|
||||
},
|
||||
networks: {
|
||||
hardhat: {
|
||||
blockGasLimit: 30000000,
|
||||
accounts: {
|
||||
mnemonic,
|
||||
},
|
||||
chainId: chainIds.hardhat,
|
||||
},
|
||||
// network: getChainConfig("{INSERT_NAME}"),
|
||||
mainnet: getChainConfig("mainnet"),
|
||||
goerli: getChainConfig("goerli"),
|
||||
sepolia: getChainConfig("sepolia"),
|
||||
"polygon-mumbai": getChainConfig("polygon-mumbai"),
|
||||
rootstock: getChainConfig("rootstock"),
|
||||
rsktestnet: getChainConfig("rsktestnet"),
|
||||
},
|
||||
paths: {
|
||||
artifacts: "./artifacts",
|
||||
cache: "./cache",
|
||||
sources: "./contracts",
|
||||
tests: "./test",
|
||||
},
|
||||
solidity: {
|
||||
version: "0.8.19",
|
||||
settings: {
|
||||
viaIR: true,
|
||||
evmVersion: "paris",
|
||||
optimizer: {
|
||||
enabled: true,
|
||||
runs: 20_000,
|
||||
details: {
|
||||
deduplicate: true,
|
||||
cse: true,
|
||||
constantOptimizer: true,
|
||||
peephole: true,
|
||||
jumpdestRemover: true,
|
||||
yul: true,
|
||||
yulDetails: {
|
||||
stackAllocation: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
typechain: {
|
||||
outDir: "src/types",
|
||||
target: "ethers-v5",
|
||||
},
|
||||
docgen: {
|
||||
pages: "files",
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
29715
package-lock.json
generated
Normal file
29715
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
96
package.json
96
package.json
@ -1,95 +1,27 @@
|
||||
{
|
||||
"name": "p2pix-smart-contracts",
|
||||
"version": "2.0.0",
|
||||
"version": "1.0.0",
|
||||
"description": "Repository for P2Pix EVM contracts to be imported by the project.",
|
||||
"homepage": "https://github.com/doiim/p2pix-smart-contracts#readme",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/doiim/p2pix-smart-contracts.git"
|
||||
},
|
||||
"author": "Filipe Soccol (doiim)",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/doiim/p2pix-smart-contracts/issues"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "shx rm -rf ./artifacts ./cache ./coverage ./src/types ./coverage.json && yarn typechain",
|
||||
"commit": "git-cz",
|
||||
"compile": "cross-env TS_NODE_TRANSPILE_ONLY=true hardhat compile",
|
||||
"typechain": "cross-env TS_NODE_TRANSPILE_ONLY=true hardhat typechain",
|
||||
"test": "hardhat test",
|
||||
"deploy1:localhost": "hardhat run scripts/1-deploy-mockToken.ts --network localhost",
|
||||
"deploy2:localhost": "hardhat run scripts/2-deploy-p2pix.ts --network localhost",
|
||||
"deploy1:goerli": "hardhat run scripts/1-deploy-mockToken.ts --network goerli",
|
||||
"deploy2:goerli": "hardhat run scripts/2-deploy-p2pix.ts --network goerli",
|
||||
"deploy1:mumbai": "hardhat run scripts/1-deploy-mockToken.ts --network polygon-mumbai",
|
||||
"deploy2:mumbai": "hardhat run scripts/2-deploy-p2pix.ts --network polygon-mumbai",
|
||||
"coverage": "hardhat coverage --solcoverjs ./.solcover.js --temp artifacts --testfiles \"test/**/*.ts\" && yarn typechain",
|
||||
"lint": "yarn lint:sol && yarn lint:ts && yarn prettier:check",
|
||||
"lint:sol": "solhint --config ./.solhint.json --max-warnings 0 \"contracts/**/*.sol\"",
|
||||
"lint:ts": "eslint --config ./.eslintrc.yaml --ignore-path ./.eslintignore --ext .js,.ts .",
|
||||
"_postinstall": "husky install",
|
||||
"postpublish": "pinst --enable",
|
||||
"prepublishOnly": "pinst --disable",
|
||||
"prettier": "prettier --config ./.prettierrc.yaml --write \"**/*.{js,json,md,sol,ts,yaml,yml}\"",
|
||||
"prettier:check": "prettier --check --config ./.prettierrc.yaml \"**/*.{js,json,md,sol,ts,yaml,yml}\""
|
||||
},
|
||||
"homepage": "https://github.com/doiim/p2pix-smart-contracts#readme",
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^17.2.0",
|
||||
"@commitlint/config-conventional": "^17.2.0",
|
||||
"@ethersproject/abi": "^5.7.0",
|
||||
"@ethersproject/abstract-signer": "^5.7.0",
|
||||
"@ethersproject/bignumber": "^5.7.0",
|
||||
"@ethersproject/bytes": "^5.7.0",
|
||||
"@ethersproject/providers": "^5.7.2",
|
||||
"@nomicfoundation/hardhat-chai-matchers": "^1.0.4",
|
||||
"@nomicfoundation/hardhat-network-helpers": "1.0.6",
|
||||
"@nomicfoundation/hardhat-toolbox": "^2.0.0",
|
||||
"@nomicfoundation/hardhat-viem": "^2.0.6",
|
||||
"@nomiclabs/hardhat-ethers": "^2.2.3",
|
||||
"@nomiclabs/hardhat-etherscan": "^3.1.2",
|
||||
"@trivago/prettier-plugin-sort-imports": "^3.4.0",
|
||||
"@typechain/ethers-v5": "^10.1.1",
|
||||
"@typechain/hardhat": "^6.1.4",
|
||||
"@types/chai": "^4.3.3",
|
||||
"@types/fs-extra": "^9.0.13",
|
||||
"@types/mocha": "^9.1.1",
|
||||
"@types/node": "^18.11.9",
|
||||
"@typescript-eslint/eslint-plugin": "^5.42.0",
|
||||
"@typescript-eslint/parser": "^5.42.0",
|
||||
"@nomiclabs/hardhat-waffle": "^2.0.3",
|
||||
"chai": "^4.3.6",
|
||||
"chalk": "4.x",
|
||||
"commitizen": "^4.2.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"cz-conventional-changelog": "^3.3.0",
|
||||
"dotenv": "^16.0.3",
|
||||
"eslint": "^8.26.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"ethers": "^5.7.2",
|
||||
"fs-extra": "^10.1.0",
|
||||
"hardhat": "^2.12.2",
|
||||
"hardhat-contract-sizer": "^2.8.0",
|
||||
"hardhat-gas-reporter": "^1.0.9",
|
||||
"husky": "^8.0.1",
|
||||
"keccak256": "^1.0.6",
|
||||
"lint-staged": "^13.0.3",
|
||||
"lodash": "^4.17.21",
|
||||
"merkletreejs": "^0.2.32",
|
||||
"mocha": "^10.1.0",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier-plugin-solidity": "^1.0.0-rc.1",
|
||||
"shx": "^0.3.4",
|
||||
"solhint": "^3.3.7",
|
||||
"solhint-plugin-prettier": "^0.0.5",
|
||||
"solidity-coverage": "^0.8.2",
|
||||
"solidity-docgen": "^0.6.0-beta.36",
|
||||
"ts-generator": "^0.1.1",
|
||||
"ts-node": "^10.9.1",
|
||||
"typechain": "^8.1.1",
|
||||
"typescript": "^5",
|
||||
"viem": "^2.23.14"
|
||||
"hardhat": "^2.12.0"
|
||||
},
|
||||
"files": [
|
||||
"/contracts"
|
||||
],
|
||||
"packageManager": "yarn@3.2.1",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
"dependencies": {
|
||||
"@openzeppelin/contracts": "^4.7.3"
|
||||
}
|
||||
}
|
||||
|
@ -1,56 +0,0 @@
|
||||
import "@nomiclabs/hardhat-ethers";
|
||||
import "@nomiclabs/hardhat-etherscan";
|
||||
import { BigNumber } from "ethers";
|
||||
import * as fs from "fs";
|
||||
import { ethers, network } from "hardhat";
|
||||
import hre from "hardhat";
|
||||
|
||||
import { Deploys } from "../test/utils/interfaces";
|
||||
|
||||
let deploysJson: Deploys;
|
||||
const supply: BigNumber = ethers.utils.parseEther("20000000");
|
||||
|
||||
const main = async () => {
|
||||
try {
|
||||
const data = fs.readFileSync(
|
||||
`./deploys/${network.name}.json`,
|
||||
{ encoding: "utf-8" },
|
||||
);
|
||||
deploysJson = JSON.parse(data);
|
||||
} catch (err) {
|
||||
console.log("Error loading Master address: ", err);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const [deployer] = await ethers.getSigners();
|
||||
console.log(`Deploying contracts with ${deployer.address}`);
|
||||
|
||||
const ERC20Factory = await ethers.getContractFactory(
|
||||
"MockToken",
|
||||
);
|
||||
const erc20 = await ERC20Factory.deploy(supply);
|
||||
await erc20.deployed();
|
||||
|
||||
deploysJson.token = erc20.address;
|
||||
console.log("🚀 Mock Token Deployed:", erc20.address);
|
||||
await erc20.deployTransaction.wait(6);
|
||||
|
||||
fs.writeFileSync(
|
||||
`./deploys/${network.name}.json`,
|
||||
JSON.stringify(deploysJson, undefined, 2),
|
||||
);
|
||||
|
||||
/* UNCOMMENT WHEN DEPLOYING TO MAINNET/PUBLIC TESTNETS */
|
||||
// verify
|
||||
// await hre.run("verify:verify", {
|
||||
// address: erc20.address,
|
||||
// constructorArguments: [supply],
|
||||
// });
|
||||
};
|
||||
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
process.exit(1);
|
||||
});
|
31
scripts/1-deploy-p2pix.js
Normal file
31
scripts/1-deploy-p2pix.js
Normal file
@ -0,0 +1,31 @@
|
||||
const fs = require('fs');
|
||||
const { network } = require("hardhat");
|
||||
|
||||
async function main() {
|
||||
|
||||
let deploysJson = {}
|
||||
|
||||
try {
|
||||
const data = fs.readFileSync(`./deploys/${network.name}.json`, {encoding:"utf-8"});
|
||||
deploysJson = JSON.parse(data);
|
||||
} catch (err) {
|
||||
console.log('Error loading Master address: ', err);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const P2PIX = await ethers.getContractFactory("P2PIX");
|
||||
const p2pix = await P2PIX.deploy(2, deploysJson.signers);
|
||||
await p2pix.deployed();
|
||||
|
||||
deploysJson.p2pix = p2pix.address
|
||||
console.log("🚀 P2PIX Deployed:", p2pix.address);
|
||||
|
||||
fs.writeFileSync(`./deploys/${network.name}.json`, JSON.stringify(deploysJson, undefined, 2));
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
31
scripts/2-deploy-mockToken.js
Normal file
31
scripts/2-deploy-mockToken.js
Normal file
@ -0,0 +1,31 @@
|
||||
const fs = require('fs');
|
||||
const { network } = require("hardhat");
|
||||
|
||||
async function main() {
|
||||
|
||||
let deploysJson = {}
|
||||
|
||||
try {
|
||||
const data = fs.readFileSync(`./deploys/${network.name}.json`, {encoding:"utf-8"});
|
||||
deploysJson = JSON.parse(data);
|
||||
} catch (err) {
|
||||
console.log('Error loading Master address: ', err);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const ERC20Factory = await ethers.getContractFactory("MockToken");
|
||||
const erc20 = await ERC20Factory.deploy(ethers.utils.parseEther('20000000', 'wei'));
|
||||
await erc20.deployed();
|
||||
|
||||
deploysJson.token = erc20.address
|
||||
console.log("🚀 Mock Token Deployed:", erc20.address);
|
||||
|
||||
fs.writeFileSync(`./deploys/${network.name}.json`, JSON.stringify(deploysJson, undefined, 2));
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
@ -1,85 +0,0 @@
|
||||
import "@nomiclabs/hardhat-ethers";
|
||||
import "@nomiclabs/hardhat-etherscan";
|
||||
import * as fs from "fs";
|
||||
import { ethers, network } from "hardhat";
|
||||
import hre from "hardhat";
|
||||
|
||||
import { Deploys } from "../test/utils/interfaces";
|
||||
|
||||
let deploysJson: Deploys;
|
||||
|
||||
const main = async () => {
|
||||
try {
|
||||
const data = fs.readFileSync(
|
||||
`./deploys/${network.name}.json`,
|
||||
{ encoding: "utf-8" },
|
||||
);
|
||||
deploysJson = JSON.parse(data);
|
||||
} catch (err) {
|
||||
console.log("Error loading Master address: ", err);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const [deployer] = await ethers.getSigners();
|
||||
console.log(`Deploying contracts with ${deployer.address}`);
|
||||
|
||||
const Reputation = await ethers.getContractFactory(
|
||||
"Reputation",
|
||||
);
|
||||
const Multicall = await ethers.getContractFactory(
|
||||
"Multicall",
|
||||
);
|
||||
const reputation = await Reputation.deploy();
|
||||
await reputation.deployed();
|
||||
const mutlicall = await Multicall.deploy();
|
||||
await mutlicall.deployed();
|
||||
|
||||
const P2PIX = await ethers.getContractFactory("P2PIX");
|
||||
const p2pix = await P2PIX.deploy(
|
||||
10,
|
||||
deploysJson.signers,
|
||||
reputation.address,
|
||||
[deploysJson.token],
|
||||
[true],
|
||||
);
|
||||
await p2pix.deployed();
|
||||
|
||||
deploysJson.p2pix = p2pix.address;
|
||||
console.log("🚀 P2PIX Deployed:", p2pix.address);
|
||||
console.log("🌠 Reputation Deployed:", reputation.address);
|
||||
console.log("🛰 Multicall Deployed:", mutlicall.address);
|
||||
await p2pix.deployTransaction.wait(6);
|
||||
|
||||
fs.writeFileSync(
|
||||
`./deploys/${network.name}.json`,
|
||||
JSON.stringify(deploysJson, undefined, 2),
|
||||
);
|
||||
|
||||
/* UNCOMMENT WHEN DEPLOYING TO MAINNET/PUBLIC TESTNETS */
|
||||
//verify
|
||||
// await hre.run("verify:verify", {
|
||||
// address: p2pix.address,
|
||||
// constructorArguments: [
|
||||
// 10,
|
||||
// deploysJson.signers,
|
||||
// reputation.address,
|
||||
// [deploysJson.token],
|
||||
// [true],
|
||||
// ],
|
||||
// });
|
||||
// await hre.run("verify:verify", {
|
||||
// address: reputation.address,
|
||||
// constructorArguments: [],
|
||||
// });
|
||||
// await hre.run("verify:verify", {
|
||||
// address: mutlicall.address,
|
||||
// constructorArguments: [],
|
||||
// });
|
||||
};
|
||||
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
process.exit(1);
|
||||
});
|
@ -1,38 +0,0 @@
|
||||
import "@nomiclabs/hardhat-ethers";
|
||||
import "@nomiclabs/hardhat-etherscan";
|
||||
import * as fs from "fs";
|
||||
import { ethers, network } from "hardhat";
|
||||
import { Deploys } from "../test/utils/interfaces";
|
||||
import { P2PIX__factory } from "../src/types";
|
||||
|
||||
let deploysJson: Deploys;
|
||||
|
||||
const main = async () => {
|
||||
try {
|
||||
const data = fs.readFileSync(
|
||||
`./deploys/${network.name}.json`,
|
||||
{ encoding: "utf-8" },
|
||||
);
|
||||
deploysJson = JSON.parse(data);
|
||||
} catch (err) {
|
||||
console.log("Error loading Master address: ", err);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const [deployer] = await ethers.getSigners();
|
||||
console.log(`Signing transactions with ${deployer.address}`);
|
||||
|
||||
const iface = new ethers.utils.Interface(P2PIX__factory.abi);
|
||||
const calldata = iface.encodeFunctionData("setDefaultLockBlocks", ["10000"]);
|
||||
|
||||
const tx = await deployer.sendTransaction({to:deploysJson.p2pix, data: calldata});
|
||||
const done = await tx.wait();
|
||||
console.log(done.transactionHash);
|
||||
};
|
||||
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
process.exit(1);
|
||||
});
|
115
test/1-deposit.test.js
Normal file
115
test/1-deposit.test.js
Normal file
@ -0,0 +1,115 @@
|
||||
const { expect } = require("chai");
|
||||
const { ethers } = require("hardhat");
|
||||
|
||||
describe("P2PIX deposit test", function () {
|
||||
|
||||
let owner, wallet2, wallet3, wallet4;
|
||||
let p2pix; // Contract instance
|
||||
let erc20; // Token instance
|
||||
let depositID;
|
||||
|
||||
it("Will deploy contracts", async function () {
|
||||
|
||||
[owner, wallet2, wallet3, wallet4] = await ethers.getSigners();
|
||||
|
||||
const ERC20Factory = await ethers.getContractFactory("MockToken");
|
||||
erc20 = await ERC20Factory.deploy(ethers.utils.parseEther('20000000', 'wei'));
|
||||
await erc20.deployed();
|
||||
|
||||
// Check initial balance
|
||||
expect(await erc20.balanceOf(owner.address)).to.equal(ethers.utils.parseEther('20000000', 'wei'));
|
||||
|
||||
const P2PIX = await ethers.getContractFactory("P2PIX");
|
||||
p2pix = await P2PIX.deploy(2, [owner.address, wallet2.address]);
|
||||
await p2pix.deployed();
|
||||
|
||||
// Verify values at deployment
|
||||
expect(await p2pix.validBacenSigners(owner.address)).to.equal(true);
|
||||
expect(await p2pix.validBacenSigners(wallet2.address)).to.equal(true);
|
||||
});
|
||||
|
||||
it("Should allow create a deposit", async function () {
|
||||
|
||||
let transaction = await erc20.approve(p2pix.address,ethers.utils.parseEther('1000'));
|
||||
await expect(transaction).to.emit(erc20, 'Approval').withArgs(
|
||||
owner.address,
|
||||
p2pix.address,
|
||||
ethers.utils.parseEther('1000')
|
||||
)
|
||||
|
||||
transaction = await p2pix.deposit(
|
||||
erc20.address,
|
||||
ethers.utils.parseEther('1000'),
|
||||
'SELLER PIX KEY',
|
||||
{value:ethers.utils.parseEther('0.1')}
|
||||
);
|
||||
depositID = ethers.utils.solidityKeccak256(['string', 'uint256'], ['SELLER PIX KEY', ethers.utils.parseEther('1000')])
|
||||
await expect(transaction).to.emit(p2pix, 'DepositAdded').withArgs(
|
||||
owner.address,
|
||||
depositID,
|
||||
erc20.address,
|
||||
ethers.utils.parseEther('0.1'),
|
||||
ethers.utils.parseEther('1000')
|
||||
)
|
||||
})
|
||||
|
||||
it("Should prevent create same deposit", async function () {
|
||||
await expect(p2pix.deposit(
|
||||
erc20.address,
|
||||
ethers.utils.parseEther('1000'),
|
||||
'SELLER PIX KEY',
|
||||
{value:ethers.utils.parseEther('0.1')}
|
||||
))
|
||||
.to.be.revertedWith('P2PIX: Deposit already exist and it is still valid');
|
||||
})
|
||||
|
||||
it("Should allow cancel the deposit", async function () {
|
||||
const transaction = await p2pix.cancelDeposit(depositID);
|
||||
await expect(transaction).to.emit(p2pix, 'DepositClosed').withArgs(
|
||||
owner.address,
|
||||
depositID
|
||||
)
|
||||
})
|
||||
|
||||
it("Should allow recreate the deposit", async function () {
|
||||
|
||||
let transaction = await erc20.approve(p2pix.address,ethers.utils.parseEther('1000'));
|
||||
await expect(transaction).to.emit(erc20, 'Approval').withArgs(
|
||||
owner.address,
|
||||
p2pix.address,
|
||||
ethers.utils.parseEther('1000')
|
||||
)
|
||||
|
||||
transaction = await p2pix.deposit(
|
||||
erc20.address,
|
||||
ethers.utils.parseEther('1000'),
|
||||
'SELLER PIX KEY',
|
||||
{value:ethers.utils.parseEther('0.1')}
|
||||
);
|
||||
depositID = ethers.utils.solidityKeccak256(['string', 'uint256'], ['SELLER PIX KEY', ethers.utils.parseEther('1000')])
|
||||
await expect(transaction).to.emit(p2pix, 'DepositAdded').withArgs(
|
||||
owner.address,
|
||||
depositID,
|
||||
erc20.address,
|
||||
ethers.utils.parseEther('0.1'),
|
||||
ethers.utils.parseEther('1000')
|
||||
)
|
||||
})
|
||||
|
||||
it("Should allow cancel the deposit again", async function () {
|
||||
const transaction = await p2pix.cancelDeposit(depositID);
|
||||
await expect(transaction).to.emit(p2pix, 'DepositClosed').withArgs(
|
||||
owner.address,
|
||||
depositID
|
||||
)
|
||||
})
|
||||
|
||||
it("Should allow withdraw the deposit", async function () {
|
||||
const transaction = await p2pix.withdraw(depositID, []);
|
||||
await expect(transaction).to.emit(p2pix, 'DepositWithdrawn').withArgs(
|
||||
owner.address,
|
||||
depositID,
|
||||
ethers.utils.parseEther('1000')
|
||||
)
|
||||
})
|
||||
})
|
241
test/2-lock-release.test.js
Normal file
241
test/2-lock-release.test.js
Normal file
@ -0,0 +1,241 @@
|
||||
const { expect } = require("chai");
|
||||
const { ethers } = require("hardhat");
|
||||
|
||||
describe("P2PIX lock/release test", function () {
|
||||
|
||||
let owner, wallet2, wallet3, wallet4;
|
||||
let p2pix; // Contract instance
|
||||
let erc20; // Token instance
|
||||
let depositID, lockID;
|
||||
|
||||
it("Will deploy contracts", async function () {
|
||||
|
||||
[owner, wallet2, wallet3, wallet4] = await ethers.getSigners();
|
||||
|
||||
const ERC20Factory = await ethers.getContractFactory("MockToken");
|
||||
erc20 = await ERC20Factory.deploy(ethers.utils.parseEther('20000000', 'wei'));
|
||||
await erc20.deployed();
|
||||
|
||||
// Check initial balance
|
||||
expect(await erc20.balanceOf(owner.address)).to.equal(ethers.utils.parseEther('20000000', 'wei'));
|
||||
|
||||
const P2PIX = await ethers.getContractFactory("P2PIX");
|
||||
p2pix = await P2PIX.deploy(3, [owner.address, wallet2.address]);
|
||||
await p2pix.deployed();
|
||||
|
||||
// Verify values at deployment
|
||||
expect(await p2pix.validBacenSigners(owner.address)).to.equal(true);
|
||||
expect(await p2pix.validBacenSigners(wallet2.address)).to.equal(true);
|
||||
expect(await p2pix.validBacenSigners(wallet3.address)).to.equal(false);
|
||||
});
|
||||
|
||||
it("Should allow create a deposit", async function () {
|
||||
|
||||
let transaction = await erc20.approve(p2pix.address,ethers.utils.parseEther('1000'));
|
||||
await expect(transaction).to.emit(erc20, 'Approval').withArgs(
|
||||
owner.address,
|
||||
p2pix.address,
|
||||
ethers.utils.parseEther('1000')
|
||||
)
|
||||
|
||||
transaction = await p2pix.deposit(
|
||||
erc20.address,
|
||||
ethers.utils.parseEther('1000'),
|
||||
'SELLER PIX KEY',
|
||||
{value:ethers.utils.parseEther('0.1')}
|
||||
);
|
||||
depositID = ethers.utils.solidityKeccak256(['string', 'uint256'], ['SELLER PIX KEY', ethers.utils.parseEther('1000')])
|
||||
await expect(transaction).to.emit(p2pix, 'DepositAdded').withArgs(
|
||||
owner.address,
|
||||
depositID,
|
||||
erc20.address,
|
||||
ethers.utils.parseEther('0.1'),
|
||||
ethers.utils.parseEther('1000')
|
||||
)
|
||||
console.log('GAS USED:', (await transaction.wait()).cumulativeGasUsed.toString())
|
||||
})
|
||||
|
||||
it("Should allow create a new lock", async function () {
|
||||
transaction = await p2pix.connect(wallet3).lock(
|
||||
depositID,
|
||||
wallet3.address,
|
||||
ethers.constants.AddressZero,
|
||||
'0',
|
||||
ethers.utils.parseEther('100'),
|
||||
[]
|
||||
)
|
||||
lockID = ethers.utils.solidityKeccak256(['bytes32', 'uint256', 'address'], [
|
||||
depositID,
|
||||
ethers.utils.parseEther('100'),
|
||||
wallet3.address
|
||||
])
|
||||
await expect(transaction).to.emit(p2pix, 'LockAdded').withArgs(
|
||||
wallet3.address,
|
||||
lockID,
|
||||
depositID,
|
||||
ethers.utils.parseEther('100')
|
||||
)
|
||||
console.log('GAS USED:', (await transaction.wait()).cumulativeGasUsed.toString())
|
||||
})
|
||||
|
||||
it("Should release the locked amount to the buyer", async function () {
|
||||
const endtoendID = '123';
|
||||
const messageToSign = ethers.utils.solidityKeccak256(['string', 'uint256', 'uint256'], [
|
||||
'SELLER PIX KEY',
|
||||
ethers.utils.parseEther('100'),
|
||||
endtoendID
|
||||
])
|
||||
// Note: messageToSign is a string, that is 66-bytes long, to sign the
|
||||
// binary value, we must convert it to the 32 byte Array that
|
||||
// the string represents
|
||||
//
|
||||
// i.e.
|
||||
// // 66-byte string
|
||||
// "0x592fa743889fc7f92ac2a37bb1f5ba1daf2a5c84741ca0e0061d243a2e6707ba"
|
||||
// ... vs ...
|
||||
// // 32 entry Uint8Array
|
||||
// [ 89, 47, 167, 67, 136, 159, ... 103, 7, 186]
|
||||
const messageHashBytes = ethers.utils.arrayify(messageToSign)
|
||||
// Sign the string message
|
||||
const flatSig = await owner.signMessage(messageHashBytes);
|
||||
// For Solidity, we need the expanded-format of a signature
|
||||
const sig = ethers.utils.splitSignature(flatSig);
|
||||
transaction = await p2pix.connect(wallet3).release(
|
||||
lockID,
|
||||
endtoendID,
|
||||
sig.r,
|
||||
sig.s,
|
||||
sig.v
|
||||
)
|
||||
await expect(transaction).to.emit(p2pix, 'LockReleased').withArgs(
|
||||
wallet3.address,
|
||||
lockID
|
||||
)
|
||||
console.log('GAS USED:', (await transaction.wait()).cumulativeGasUsed.toString())
|
||||
expect(await erc20.balanceOf(wallet3.address)).to.equal(ethers.utils.parseEther('100'));
|
||||
})
|
||||
|
||||
it("Should allow recreate same lock", async function () {
|
||||
transaction = await p2pix.connect(wallet3).lock(
|
||||
depositID,
|
||||
wallet3.address,
|
||||
ethers.constants.AddressZero,
|
||||
'0',
|
||||
ethers.utils.parseEther('100'),
|
||||
[]
|
||||
)
|
||||
lockID = ethers.utils.solidityKeccak256(['bytes32', 'uint256', 'address'], [
|
||||
depositID,
|
||||
ethers.utils.parseEther('100'),
|
||||
wallet3.address
|
||||
])
|
||||
await expect(transaction).to.emit(p2pix, 'LockAdded').withArgs(
|
||||
wallet3.address,
|
||||
lockID,
|
||||
depositID,
|
||||
ethers.utils.parseEther('100'),
|
||||
)
|
||||
})
|
||||
|
||||
it("Should prevent create again same lock", async function () {
|
||||
await expect(p2pix.connect(wallet3).lock(
|
||||
depositID,
|
||||
wallet3.address,
|
||||
ethers.constants.AddressZero,
|
||||
'0',
|
||||
ethers.utils.parseEther('100'),
|
||||
[]
|
||||
)).to.be.revertedWith('P2PIX: Another lock with same ID is not expired yet');
|
||||
})
|
||||
|
||||
it("Should release the locked amount to the buyer", async function () {
|
||||
const endtoendID = '124';
|
||||
const messageToSign = ethers.utils.solidityKeccak256(['string', 'uint256', 'uint256'], [
|
||||
'SELLER PIX KEY',
|
||||
ethers.utils.parseEther('100'),
|
||||
endtoendID
|
||||
])
|
||||
const messageHashBytes = ethers.utils.arrayify(messageToSign)
|
||||
const flatSig = await owner.signMessage(messageHashBytes);
|
||||
const sig = ethers.utils.splitSignature(flatSig);
|
||||
transaction = await p2pix.connect(wallet3).release(
|
||||
lockID,
|
||||
endtoendID,
|
||||
sig.r,
|
||||
sig.s,
|
||||
sig.v
|
||||
)
|
||||
expect(await erc20.balanceOf(wallet3.address)).to.equal(ethers.utils.parseEther('200'));
|
||||
})
|
||||
|
||||
it("Should prevent release again the lock", async function () {
|
||||
const endtoendID = '125';
|
||||
const messageToSign = ethers.utils.solidityKeccak256(['string', 'uint256', 'uint256'], [
|
||||
'SELLER PIX KEY',
|
||||
ethers.utils.parseEther('100'),
|
||||
endtoendID
|
||||
])
|
||||
const messageHashBytes = ethers.utils.arrayify(messageToSign)
|
||||
const flatSig = await owner.signMessage(messageHashBytes);
|
||||
const sig = ethers.utils.splitSignature(flatSig);
|
||||
await expect(p2pix.connect(wallet3).release(
|
||||
lockID,
|
||||
endtoendID,
|
||||
sig.r,
|
||||
sig.s,
|
||||
sig.v
|
||||
)).to.be.revertedWith('P2PIX: Lock already released or returned');
|
||||
})
|
||||
|
||||
it("Should prevent create a 800 lock", async function () {
|
||||
await expect(p2pix.connect(wallet3).lock(
|
||||
depositID,
|
||||
wallet3.address,
|
||||
ethers.constants.AddressZero,
|
||||
'0',
|
||||
ethers.utils.parseEther('900'),
|
||||
[]
|
||||
)).to.be.revertedWith('P2PIX: Not enough token remaining on deposit');
|
||||
})
|
||||
|
||||
it("Should allow recreate same lock again", async function () {
|
||||
transaction = await p2pix.connect(wallet3).lock(
|
||||
depositID,
|
||||
wallet3.address,
|
||||
ethers.constants.AddressZero,
|
||||
'0',
|
||||
ethers.utils.parseEther('100'),
|
||||
[]
|
||||
)
|
||||
lockID = ethers.utils.solidityKeccak256(['bytes32', 'uint256', 'address'], [
|
||||
depositID,
|
||||
ethers.utils.parseEther('100'),
|
||||
wallet3.address
|
||||
])
|
||||
await expect(transaction).to.emit(p2pix, 'LockAdded').withArgs(
|
||||
wallet3.address,
|
||||
lockID,
|
||||
depositID,
|
||||
ethers.utils.parseEther('100')
|
||||
)
|
||||
})
|
||||
|
||||
it("Should allow unlock expired lock", async function () {
|
||||
await expect(p2pix.unlockExpired([lockID]))
|
||||
.to.be.revertedWith('P2PIX: Lock not expired or already released');
|
||||
await network.provider.send("evm_mine");
|
||||
await network.provider.send("evm_mine");
|
||||
await network.provider.send("evm_mine");
|
||||
transaction = await p2pix.unlockExpired([lockID])
|
||||
await expect(transaction).to.emit(p2pix, 'LockReturned').withArgs(
|
||||
wallet3.address,
|
||||
lockID
|
||||
)
|
||||
})
|
||||
|
||||
it("Should prevent unlock again", async function () {
|
||||
await expect(p2pix.unlockExpired([lockID]))
|
||||
.to.be.revertedWith('P2PIX: Lock not expired or already released');
|
||||
})
|
||||
|
||||
})
|
@ -1,95 +0,0 @@
|
||||
import "@nomicfoundation/hardhat-chai-matchers";
|
||||
import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
|
||||
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
|
||||
import { expect } from "chai";
|
||||
import { ethers, network } from "hardhat";
|
||||
|
||||
import { Reputation } from "../src/types";
|
||||
import { curve, repFixture } from "./utils/fixtures";
|
||||
|
||||
describe("Reputation", () => {
|
||||
// contract deployer/admin
|
||||
let owner: SignerWithAddress;
|
||||
// Reputation Interface instance;
|
||||
let reputation: Reputation;
|
||||
|
||||
before("Set signers and reset network", async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
[owner] = await (ethers as any).getSigners();
|
||||
|
||||
await network.provider.send("hardhat_reset");
|
||||
});
|
||||
beforeEach("Load deployment fixtures", async () => {
|
||||
({ reputation } = await loadFixture(repFixture));
|
||||
});
|
||||
|
||||
// describe("Limiter", async () => {
|
||||
// it("Curve reliability", async () => {
|
||||
// const tx1 = await reputation.connect(owner).limiter(0);
|
||||
// const tx2 = await reputation.limiter(500);
|
||||
// const tx3 = await reputation
|
||||
// .connect(owner)
|
||||
// .limiter(444444);
|
||||
// const tx4 = await reputation.limiter(988700);
|
||||
|
||||
// expect(tx1).to.eq(curve(0));
|
||||
// expect(tx2).to.eq(curve(500));
|
||||
// expect(tx3).to.eq(curve(444444));
|
||||
// expect(tx4).to.eq(curve(988700));
|
||||
// });
|
||||
// });
|
||||
|
||||
describe("Limiter", async () => {
|
||||
it("Curve reliability", async () => {
|
||||
const testCases = [
|
||||
{
|
||||
x: 0,
|
||||
expected: curve(0),
|
||||
},
|
||||
{
|
||||
x: 500,
|
||||
expected: curve(500),
|
||||
},
|
||||
{
|
||||
x: 444444,
|
||||
expected: curve(444444),
|
||||
},
|
||||
{
|
||||
x: 988700,
|
||||
expected: curve(988700),
|
||||
},
|
||||
{
|
||||
x: Number.MAX_SAFE_INTEGER,
|
||||
shouldRevert: "overflow",
|
||||
},
|
||||
{
|
||||
x: Number.POSITIVE_INFINITY,
|
||||
shouldRevert: "overflow",
|
||||
},
|
||||
{
|
||||
x: Number.NEGATIVE_INFINITY,
|
||||
shouldRevert: "overflow",
|
||||
},
|
||||
{
|
||||
x: -1,
|
||||
shouldRevert: "value out-of-bounds",
|
||||
},
|
||||
{
|
||||
x: Number.NaN,
|
||||
shouldRevert: "invalid BigNumber string",
|
||||
},
|
||||
];
|
||||
|
||||
for (const testCase of testCases) {
|
||||
if (testCase.shouldRevert != undefined) {
|
||||
await expect(reputation.limiter(testCase.x)).to.be
|
||||
.rejected;
|
||||
} else {
|
||||
const result = await reputation.limiter(testCase.x);
|
||||
expect(result).to.eq(testCase.expected).and.to.be
|
||||
.ok;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
@ -1,7 +0,0 @@
|
||||
/* eslint-disable no-useless-escape */
|
||||
|
||||
describe("_", () => {
|
||||
console.log(
|
||||
"/// ______ __\r\n/// .-----.|__ |.-----.|__|.--.--.\r\n/// | _ || __|| _ || ||_ _|\r\n/// | __||______|| __||__||__.__|\r\n/// |__| |__|\r\n///",
|
||||
);
|
||||
});
|
@ -1,116 +0,0 @@
|
||||
// import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
|
||||
// import { expect } from "chai";
|
||||
// import { ethers } from "hardhat";
|
||||
|
||||
// import { MockToken, P2PIX } from "../src/types";
|
||||
|
||||
// describe("P2PIX deposit test", () => {
|
||||
// let owner: SignerWithAddress;
|
||||
// let wallet2: SignerWithAddress;
|
||||
// // let wallet3: SignerWithAddress;
|
||||
// // let wallet4: SignerWithAddress;
|
||||
// let p2pix: P2PIX; // Contract instance
|
||||
// let erc20: MockToken; // Token instance
|
||||
|
||||
// it("Will deploy contracts", async () => {
|
||||
// [owner, wallet2 /* wallet3, wallet4 */] =
|
||||
// await ethers.getSigners();
|
||||
|
||||
// const ERC20Factory = await ethers.getContractFactory(
|
||||
// "MockToken",
|
||||
// );
|
||||
// erc20 = await ERC20Factory.deploy(
|
||||
// ethers.utils.parseEther("20000000"),
|
||||
// );
|
||||
// await erc20.deployed();
|
||||
|
||||
// // Check initial balance
|
||||
// expect(await erc20.balanceOf(owner.address)).to.equal(
|
||||
// ethers.utils.parseEther("20000000"),
|
||||
// );
|
||||
|
||||
// const P2PIX = await ethers.getContractFactory("P2PIX");
|
||||
// p2pix = await P2PIX.deploy(2, [
|
||||
// owner.address,
|
||||
// wallet2.address,
|
||||
// ]);
|
||||
// await p2pix.deployed();
|
||||
|
||||
// const ownerKey = await p2pix._castAddrToKey(owner.address);
|
||||
// const wallet2Key = await p2pix._castAddrToKey(wallet2.address);
|
||||
|
||||
// // Verify values at deployment
|
||||
// expect(
|
||||
// await p2pix.callStatic.validBacenSigners(ownerKey),
|
||||
// ).to.equal(true);
|
||||
// expect(
|
||||
// await p2pix.validBacenSigners(wallet2Key),
|
||||
// ).to.equal(true);
|
||||
// });
|
||||
|
||||
// it("Should allow create a deposit", async () => {
|
||||
// let transaction = await erc20.approve(
|
||||
// p2pix.address,
|
||||
// ethers.utils.parseEther("2000"),
|
||||
// );
|
||||
// await expect(transaction)
|
||||
// .to.emit(erc20, "Approval")
|
||||
// .withArgs(
|
||||
// owner.address,
|
||||
// p2pix.address,
|
||||
// ethers.utils.parseEther("2000"),
|
||||
// );
|
||||
|
||||
// transaction = await p2pix.deposit(
|
||||
// erc20.address,
|
||||
// ethers.utils.parseEther("1000"),
|
||||
// "SELLER PIX KEY",
|
||||
// // { value: ethers.utils.parseEther("0.1") },
|
||||
// );
|
||||
// await expect(transaction)
|
||||
// .to.emit(p2pix, "DepositAdded")
|
||||
// .withArgs(
|
||||
// owner.address,
|
||||
// 0,
|
||||
// erc20.address,
|
||||
// // ethers.utils.parseEther("0.1"),
|
||||
// ethers.utils.parseEther("1000"),
|
||||
// );
|
||||
// });
|
||||
|
||||
// it("Should allow create second deposit", async () => {
|
||||
// const transaction = await p2pix.deposit(
|
||||
// erc20.address,
|
||||
// ethers.utils.parseEther("1000"),
|
||||
// "SELLER PIX KEY",
|
||||
// // { value: ethers.utils.parseEther("0.1") },
|
||||
// );
|
||||
// await expect(transaction)
|
||||
// .to.emit(p2pix, "DepositAdded")
|
||||
// .withArgs(
|
||||
// owner.address,
|
||||
// 1,
|
||||
// erc20.address,
|
||||
// // ethers.utils.parseEther("0.1"),
|
||||
// ethers.utils.parseEther("1000"),
|
||||
// );
|
||||
// });
|
||||
|
||||
// it("Should allow cancel first deposit", async () => {
|
||||
// const transaction = await p2pix.cancelDeposit(0);
|
||||
// await expect(transaction)
|
||||
// .to.emit(p2pix, "DepositClosed")
|
||||
// .withArgs(owner.address, 0);
|
||||
// });
|
||||
|
||||
// it("Should allow withdraw the deposit", async () => {
|
||||
// const transaction = await p2pix.withdraw(0, []);
|
||||
// await expect(transaction)
|
||||
// .to.emit(p2pix, "DepositWithdrawn")
|
||||
// .withArgs(
|
||||
// owner.address,
|
||||
// 0,
|
||||
// ethers.utils.parseEther("1000"),
|
||||
// );
|
||||
// });
|
||||
// });
|
@ -1,305 +0,0 @@
|
||||
// import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
|
||||
// import { expect } from "chai";
|
||||
// import { ethers, network } from "hardhat";
|
||||
// import { P2PixErrors } from "./utils/errors";
|
||||
|
||||
// import { MockToken, P2PIX } from "../src/types";
|
||||
|
||||
// describe("P2PIX deposit test", () => {
|
||||
// let owner: SignerWithAddress;
|
||||
// let wallet2: SignerWithAddress;
|
||||
// let wallet3: SignerWithAddress;
|
||||
// // let wallet4: SignerWithAddress;
|
||||
// let p2pix: P2PIX; // Contract instance
|
||||
// let erc20: MockToken; // Token instance
|
||||
// let lockID: string;
|
||||
|
||||
// it("Will deploy contracts", async () => {
|
||||
// [owner, wallet2, wallet3 /* , wallet4 */] =
|
||||
// await ethers.getSigners();
|
||||
|
||||
// const ERC20Factory = await ethers.getContractFactory(
|
||||
// "MockToken",
|
||||
// );
|
||||
// erc20 = await ERC20Factory.deploy(
|
||||
// ethers.utils.parseEther("20000000"),
|
||||
// );
|
||||
// await erc20.deployed();
|
||||
|
||||
// // Check initial balance
|
||||
// expect(await erc20.balanceOf(owner.address)).to.equal(
|
||||
// ethers.utils.parseEther("20000000"),
|
||||
// );
|
||||
|
||||
// const P2PIX = await ethers.getContractFactory("P2PIX");
|
||||
// p2pix = await P2PIX.deploy(3, [
|
||||
// owner.address,
|
||||
// wallet2.address,
|
||||
// ]);
|
||||
// await p2pix.deployed();
|
||||
|
||||
// const ownerKey = await p2pix._castAddrToKey(owner.address);
|
||||
// const wallet2key = await p2pix._castAddrToKey(wallet2.address);
|
||||
// const wallet3key = await p2pix._castAddrToKey(wallet3.address);
|
||||
|
||||
// // Verify values at deployment
|
||||
// expect(
|
||||
// await p2pix.validBacenSigners(ownerKey),
|
||||
// ).to.equal(true);
|
||||
// expect(
|
||||
// await p2pix.validBacenSigners(wallet2key),
|
||||
// ).to.equal(true);
|
||||
// expect(
|
||||
// await p2pix.validBacenSigners(wallet3key),
|
||||
// ).to.equal(false);
|
||||
// });
|
||||
|
||||
// it("Should allow create a deposit", async () => {
|
||||
// let transaction = await erc20.approve(
|
||||
// p2pix.address,
|
||||
// ethers.utils.parseEther("1000"),
|
||||
// );
|
||||
// await expect(transaction)
|
||||
// .to.emit(erc20, "Approval")
|
||||
// .withArgs(
|
||||
// owner.address,
|
||||
// p2pix.address,
|
||||
// ethers.utils.parseEther("1000"),
|
||||
// );
|
||||
// transaction = await p2pix.deposit(
|
||||
// erc20.address,
|
||||
// ethers.utils.parseEther("1000"),
|
||||
// "SELLER PIX KEY",
|
||||
// // { value: ethers.utils.parseEther("0.1") },
|
||||
// );
|
||||
// await expect(transaction)
|
||||
// .to.emit(p2pix, "DepositAdded")
|
||||
// .withArgs(
|
||||
// owner.address,
|
||||
// 0,
|
||||
// erc20.address,
|
||||
// // ethers.utils.parseEther("0.1"),
|
||||
// ethers.utils.parseEther("1000"),
|
||||
// );
|
||||
// console.log(
|
||||
// "GAS USED:",
|
||||
// (await transaction.wait()).cumulativeGasUsed.toString(),
|
||||
// );
|
||||
// });
|
||||
|
||||
// it("Should allow create a new lock", async () => {
|
||||
// const transaction = await p2pix
|
||||
// .connect(wallet3)
|
||||
// .lock(
|
||||
// 0,
|
||||
// wallet3.address,
|
||||
// ethers.constants.AddressZero,
|
||||
// "0",
|
||||
// ethers.utils.parseEther("100"),
|
||||
// [],
|
||||
// );
|
||||
// lockID = ethers.utils.solidityKeccak256(
|
||||
// ["uint256", "uint256", "address"],
|
||||
// [0, ethers.utils.parseEther("100"), wallet3.address],
|
||||
// );
|
||||
// await expect(transaction)
|
||||
// .to.emit(p2pix, "LockAdded")
|
||||
// .withArgs(
|
||||
// wallet3.address,
|
||||
// lockID,
|
||||
// 0,
|
||||
// ethers.utils.parseEther("100"),
|
||||
// );
|
||||
// console.log(
|
||||
// "GAS USED:",
|
||||
// (await transaction.wait()).cumulativeGasUsed.toString(),
|
||||
// );
|
||||
// });
|
||||
|
||||
// it("Should release the locked amount to the buyer", async () => {
|
||||
// const endtoendID = "123";
|
||||
// const messageToSign = ethers.utils.solidityKeccak256(
|
||||
// ["string", "uint256", "uint256"],
|
||||
// [
|
||||
// "SELLER PIX KEY",
|
||||
// ethers.utils.parseEther("100"),
|
||||
// endtoendID,
|
||||
// ],
|
||||
// );
|
||||
// // Note: messageToSign is a string, that is 66-bytes long, to sign the
|
||||
// // binary value, we must convert it to the 32 byte Array that
|
||||
// // the string represents
|
||||
// //
|
||||
// // i.e.
|
||||
// // // 66-byte string
|
||||
// // "0x592fa743889fc7f92ac2a37bb1f5ba1daf2a5c84741ca0e0061d243a2e6707ba"
|
||||
// // ... vs ...
|
||||
// // // 32 entry Uint8Array
|
||||
// // [ 89, 47, 167, 67, 136, 159, ... 103, 7, 186]
|
||||
// const messageHashBytes =
|
||||
// ethers.utils.arrayify(messageToSign);
|
||||
// // Sign the string message
|
||||
// const flatSig = await owner.signMessage(messageHashBytes);
|
||||
// // For Solidity, we need the expanded-format of a signature
|
||||
// const sig = ethers.utils.splitSignature(flatSig);
|
||||
// const transaction = await p2pix
|
||||
// .connect(wallet3)
|
||||
// .release(lockID, endtoendID, sig.r, sig.s, sig.v);
|
||||
// await expect(transaction)
|
||||
// .to.emit(p2pix, "LockReleased")
|
||||
// .withArgs(wallet3.address, lockID);
|
||||
// console.log(
|
||||
// "GAS USED:",
|
||||
// (await transaction.wait()).cumulativeGasUsed.toString(),
|
||||
// );
|
||||
// expect(await erc20.balanceOf(wallet3.address)).to.equal(
|
||||
// ethers.utils.parseEther("100"),
|
||||
// );
|
||||
// });
|
||||
|
||||
// it("Should allow recreate same lock", async () => {
|
||||
// const transaction = await p2pix
|
||||
// .connect(wallet3)
|
||||
// .lock(
|
||||
// 0,
|
||||
// wallet3.address,
|
||||
// ethers.constants.AddressZero,
|
||||
// "0",
|
||||
// ethers.utils.parseEther("100"),
|
||||
// [],
|
||||
// );
|
||||
// lockID = ethers.utils.solidityKeccak256(
|
||||
// ["uint256", "uint256", "address"],
|
||||
// [0, ethers.utils.parseEther("100"), wallet3.address],
|
||||
// );
|
||||
// await expect(transaction)
|
||||
// .to.emit(p2pix, "LockAdded")
|
||||
// .withArgs(
|
||||
// wallet3.address,
|
||||
// lockID,
|
||||
// 0,
|
||||
// ethers.utils.parseEther("100"),
|
||||
// );
|
||||
// });
|
||||
|
||||
// it("Should prevent create again same lock", async () => {
|
||||
// await expect(
|
||||
// p2pix
|
||||
// .connect(wallet3)
|
||||
// .lock(
|
||||
// 0,
|
||||
// wallet3.address,
|
||||
// ethers.constants.AddressZero,
|
||||
// "0",
|
||||
// ethers.utils.parseEther("100"),
|
||||
// [],
|
||||
// ),
|
||||
// ).to.be.revertedWithCustomError(p2pix, P2PixErrors.NotExpired);
|
||||
// });
|
||||
|
||||
// it("Should release the locked amount to the buyer", async () => {
|
||||
// const endtoendID = "124";
|
||||
// const messageToSign = ethers.utils.solidityKeccak256(
|
||||
// ["string", "uint256", "uint256"],
|
||||
// [
|
||||
// "SELLER PIX KEY",
|
||||
// ethers.utils.parseEther("100"),
|
||||
// endtoendID,
|
||||
// ],
|
||||
// );
|
||||
// const messageHashBytes =
|
||||
// ethers.utils.arrayify(messageToSign);
|
||||
// const flatSig = await owner.signMessage(messageHashBytes);
|
||||
// const sig = ethers.utils.splitSignature(flatSig);
|
||||
// await p2pix
|
||||
// .connect(wallet3)
|
||||
// .release(lockID, endtoendID, sig.r, sig.s, sig.v);
|
||||
// expect(await erc20.balanceOf(wallet3.address)).to.equal(
|
||||
// ethers.utils.parseEther("200"),
|
||||
// );
|
||||
// });
|
||||
|
||||
// it("Should prevent release again the lock", async () => {
|
||||
// const endtoendID = "125";
|
||||
// const messageToSign = ethers.utils.solidityKeccak256(
|
||||
// ["string", "uint256", "uint256"],
|
||||
// [
|
||||
// "SELLER PIX KEY",
|
||||
// ethers.utils.parseEther("100"),
|
||||
// endtoendID,
|
||||
// ],
|
||||
// );
|
||||
// const messageHashBytes =
|
||||
// ethers.utils.arrayify(messageToSign);
|
||||
// const flatSig = await owner.signMessage(messageHashBytes);
|
||||
// const sig = ethers.utils.splitSignature(flatSig);
|
||||
// await expect(
|
||||
// p2pix
|
||||
// .connect(wallet3)
|
||||
// .release(lockID, endtoendID, sig.r, sig.s, sig.v),
|
||||
// ).to.be.revertedWithCustomError(p2pix, P2PixErrors.AlreadyReleased);
|
||||
// });
|
||||
|
||||
// it("Should prevent create a 900 lock", async () => {
|
||||
// await expect(
|
||||
// p2pix
|
||||
// .connect(wallet3)
|
||||
// .lock(
|
||||
// 0,
|
||||
// wallet3.address,
|
||||
// ethers.constants.AddressZero,
|
||||
// "0",
|
||||
// ethers.utils.parseEther("900"),
|
||||
// [],
|
||||
// ),
|
||||
// ).to.be.revertedWithCustomError(
|
||||
// p2pix, P2PixErrors.NotEnoughTokens);
|
||||
// });
|
||||
|
||||
// it("Should allow recreate same lock again", async () => {
|
||||
// const transaction = await p2pix
|
||||
// .connect(wallet3)
|
||||
// .lock(
|
||||
// 0,
|
||||
// wallet3.address,
|
||||
// ethers.constants.AddressZero,
|
||||
// "0",
|
||||
// ethers.utils.parseEther("100"),
|
||||
// [],
|
||||
// );
|
||||
// lockID = ethers.utils.solidityKeccak256(
|
||||
// ["uint256", "uint256", "address"],
|
||||
// [0, ethers.utils.parseEther("100"), wallet3.address],
|
||||
// );
|
||||
// await expect(transaction)
|
||||
// .to.emit(p2pix, "LockAdded")
|
||||
// .withArgs(
|
||||
// wallet3.address,
|
||||
// lockID,
|
||||
// 0,
|
||||
// ethers.utils.parseEther("100"),
|
||||
// );
|
||||
// });
|
||||
|
||||
// it("Should allow unlock expired lock", async () => {
|
||||
// await expect(
|
||||
// p2pix.unlockExpired([lockID]),
|
||||
// ).to.be.revertedWithCustomError(
|
||||
// p2pix, P2PixErrors.NotExpired);
|
||||
|
||||
// await network.provider.send("evm_mine");
|
||||
// await network.provider.send("evm_mine");
|
||||
// await network.provider.send("evm_mine");
|
||||
// const transaction = await p2pix.unlockExpired([lockID]);
|
||||
// await expect(transaction)
|
||||
// .to.emit(p2pix, "LockReturned")
|
||||
// .withArgs(wallet3.address, lockID);
|
||||
// });
|
||||
|
||||
// it("Should prevent unlock again", async () => {
|
||||
// await expect(
|
||||
// p2pix.unlockExpired([lockID]),
|
||||
// ).to.be.revertedWithCustomError(
|
||||
// p2pix, P2PixErrors.NotExpired);
|
||||
// });
|
||||
// });
|
2092
test/p2pix.test.ts
2092
test/p2pix.test.ts
File diff suppressed because it is too large
Load Diff
@ -1,22 +0,0 @@
|
||||
export enum P2PixErrors {
|
||||
OnlySeller = "OnlySeller",
|
||||
NotExpired = "NotExpired",
|
||||
LoopOverflow = "LoopOverflow",
|
||||
InvalidDeposit = "InvalidDeposit",
|
||||
NotEnoughTokens = "NotEnoughTokens",
|
||||
AlreadyReleased = "AlreadyReleased",
|
||||
TxAlreadyUsed = "TxAlreadyUsed",
|
||||
InvalidSigner = "InvalidSigner",
|
||||
Unauthorized = "Unauthorized",
|
||||
TokenDenied = "TokenDenied",
|
||||
NoTokens = "NoTokens",
|
||||
LengthMismatch = "LengthMismatch",
|
||||
AddressDenied = "AddressDenied",
|
||||
AmountNotAllowed = "AmountNotAllowed",
|
||||
LockExpired = "LockExpired",
|
||||
EmptyPixTarget = "EmptyPixTarget",
|
||||
MaxBalExceeded = "MaxBalExceeded",
|
||||
NotInitialized = "NotInitialized",
|
||||
DecOverflow = "DecOverflow",
|
||||
CallFailed = "CallFailed",
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
|
||||
import { BigNumber, Signer } from "ethers";
|
||||
import { ethers } from "hardhat";
|
||||
import keccak256 from "keccak256";
|
||||
import { MerkleTree } from "merkletreejs";
|
||||
|
||||
import {
|
||||
MockToken,
|
||||
Multicall,
|
||||
P2PIX,
|
||||
P2PIX__factory,
|
||||
Reputation,
|
||||
} from "../../src/types";
|
||||
|
||||
import { Call, RepFixture, P2PixAndReputation, DepositArgs, LockArgs, ReleaseArgs } from "./interfaces";
|
||||
|
||||
|
||||
// exported constants
|
||||
export const getSignerAddrs = (
|
||||
amount: number,
|
||||
addrs: SignerWithAddress[],
|
||||
): string[] => {
|
||||
return addrs.slice(0, amount).map(({ address }) => address);
|
||||
};
|
||||
|
||||
export const getBnFrom = (nums: number[]): BigNumber[] => {
|
||||
const bns = nums.map(num => ethers.BigNumber.from(num));
|
||||
return bns;
|
||||
};
|
||||
|
||||
export const getLockData = (
|
||||
addr: string,
|
||||
locks: BigNumber[][],
|
||||
): Call[] => {
|
||||
const iface = new ethers.utils.Interface(
|
||||
P2PIX__factory.abi,
|
||||
);
|
||||
return locks.map(lock => ({
|
||||
target: addr,
|
||||
callData: iface.encodeFunctionData("getLocksStatus", [
|
||||
lock,
|
||||
]),
|
||||
}));
|
||||
};
|
||||
|
||||
export const randomSigners = (amount: number): Signer[] => {
|
||||
const signers: Signer[] = [];
|
||||
for (let i = 0; i < amount; i++) {
|
||||
signers.push(ethers.Wallet.createRandom());
|
||||
}
|
||||
return signers;
|
||||
};
|
||||
|
||||
export const getError = (Error: string) =>
|
||||
ethers.utils
|
||||
.keccak256(ethers.utils.toUtf8Bytes(Error))
|
||||
.slice(0, 10);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export const padBuffer = (addr: any) => {
|
||||
return Buffer.from(
|
||||
addr.substr(2).padStart(32 * 2, 0),
|
||||
"hex",
|
||||
);
|
||||
};
|
||||
|
||||
export const curve = (x: number): number => {
|
||||
return Math.round(
|
||||
1 + (10 ** 6 * x) / Math.sqrt(2.5 * 10 ** 11 + x * x),
|
||||
);
|
||||
};
|
||||
|
||||
// exported async functions
|
||||
export async function repFixture(): Promise<RepFixture> {
|
||||
const Reputation = await ethers.getContractFactory(
|
||||
"Reputation",
|
||||
);
|
||||
const reputation =
|
||||
(await Reputation.deploy()) as Reputation;
|
||||
|
||||
return { reputation };
|
||||
}
|
||||
|
||||
export async function p2pixFixture(): Promise<P2PixAndReputation> {
|
||||
const validSigners = getSignerAddrs(
|
||||
2,
|
||||
await ethers.getSigners(),
|
||||
);
|
||||
|
||||
const Reputation = await ethers.getContractFactory(
|
||||
"Reputation",
|
||||
);
|
||||
const reputation =
|
||||
(await Reputation.deploy()) as Reputation;
|
||||
|
||||
const ERC20 = await ethers.getContractFactory("MockToken");
|
||||
const erc20 = (await ERC20.deploy(
|
||||
ethers.utils.parseEther("20000000"), // 20M
|
||||
)) as MockToken;
|
||||
|
||||
const P2PIX = await ethers.getContractFactory("P2PIX");
|
||||
const p2pix = (await P2PIX.deploy(
|
||||
10,
|
||||
validSigners,
|
||||
reputation.address,
|
||||
[erc20.address],
|
||||
[true],
|
||||
)) as P2PIX;
|
||||
|
||||
const Multicall = await ethers.getContractFactory(
|
||||
"Multicall",
|
||||
);
|
||||
const multicall = (await Multicall.deploy()) as Multicall;
|
||||
|
||||
const signers = await ethers.getSigners();
|
||||
const whitelisted = signers.slice(0, 2);
|
||||
const leaves = whitelisted.map(account =>
|
||||
padBuffer(account.address),
|
||||
);
|
||||
const tree = new MerkleTree(leaves, keccak256, {
|
||||
sort: true,
|
||||
});
|
||||
const merkleRoot: string = tree.getHexRoot();
|
||||
const proof: string[] = tree.getHexProof(
|
||||
padBuffer(whitelisted[1].address),
|
||||
);
|
||||
|
||||
return {
|
||||
multicall,
|
||||
reputation,
|
||||
erc20,
|
||||
p2pix,
|
||||
merkleRoot,
|
||||
proof,
|
||||
};
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
import { BigNumber } from "ethers";
|
||||
|
||||
import {
|
||||
MockToken,
|
||||
Multicall,
|
||||
P2PIX,
|
||||
Reputation,
|
||||
} from "../../src/types";
|
||||
|
||||
|
||||
// exported interfaces
|
||||
export interface Deploys {
|
||||
signers: string[];
|
||||
p2pix: string;
|
||||
token: string;
|
||||
}
|
||||
|
||||
export interface DepositArgs {
|
||||
pixTarget: string;
|
||||
allowlistRoot: string;
|
||||
token: string;
|
||||
amount: BigNumber;
|
||||
valid: boolean;
|
||||
}
|
||||
|
||||
export interface LockArgs {
|
||||
seller: string;
|
||||
token: string;
|
||||
amount: BigNumber;
|
||||
merkleProof: string[];
|
||||
expiredLocks: BigNumber[];
|
||||
}
|
||||
|
||||
export interface ReleaseArgs {
|
||||
lockID: BigNumber;
|
||||
pixTimestamp: string;
|
||||
signature: string;
|
||||
}
|
||||
|
||||
export interface Lock {
|
||||
counter: BigNumber;
|
||||
expirationBlock: BigNumber;
|
||||
pixTarget: string;
|
||||
amount: BigNumber;
|
||||
token: string;
|
||||
buyerAddress: string;
|
||||
seller: string;
|
||||
}
|
||||
|
||||
export interface Call {
|
||||
target: string;
|
||||
callData: string;
|
||||
}
|
||||
|
||||
export interface Result {
|
||||
success: boolean;
|
||||
returnData: string;
|
||||
}
|
||||
|
||||
export interface P2pixFixture {
|
||||
p2pix: P2PIX;
|
||||
erc20: MockToken;
|
||||
proof: string[];
|
||||
merkleRoot: string;
|
||||
}
|
||||
|
||||
export interface RepFixture {
|
||||
reputation: Reputation;
|
||||
}
|
||||
|
||||
export interface MtcFixture {
|
||||
multicall: Multicall;
|
||||
}
|
||||
|
||||
export type P2PixAndReputation = P2pixFixture &
|
||||
RepFixture &
|
||||
MtcFixture;
|
@ -1,22 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"esModuleInterop": true,
|
||||
"experimentalDecorators": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"lib": ["es6"],
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"noImplicitAny": true,
|
||||
"removeComments": true,
|
||||
"resolveJsonModule": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"target": "es6"
|
||||
},
|
||||
"exclude": ["node_modules"],
|
||||
"files": ["./hardhat.config.ts"],
|
||||
"include": ["src/**/*", "test/**/*", "scripts/**/*"]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user