bond to override lock limit
This commit is contained in:
parent
e57428525b
commit
b2198306e6
@ -44,4 +44,5 @@ abstract contract Constants {
|
||||
uint256 constant MAXBALANCE_UPPERBOUND = 1e8 ether;
|
||||
uint256 constant REPUTATION_LOWERBOUND = 1e2 ether;
|
||||
uint256 constant LOCKAMOUNT_UPPERBOUND = 1e6 ether;
|
||||
uint256 constant BOND_DIVISOR = 4; // 6,25%
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ library DataTypes {
|
||||
ERC20 token;
|
||||
address buyerAddress;
|
||||
address seller;
|
||||
bool bond;
|
||||
}
|
||||
|
||||
// prettier-ignore
|
||||
|
@ -135,7 +135,8 @@ contract P2PIX is BaseUtils {
|
||||
ERC20 token,
|
||||
uint80 amount,
|
||||
bytes32[] calldata merkleProof,
|
||||
uint256[] calldata expiredLocks
|
||||
uint256[] calldata expiredLocks,
|
||||
bool bond
|
||||
) public nonReentrant returns (uint256 lockID) {
|
||||
unlockExpired(expiredLocks);
|
||||
|
||||
@ -154,10 +155,17 @@ contract P2PIX is BaseUtils {
|
||||
|
||||
bytes32 _pixTarget = getPixTarget(seller, token);
|
||||
|
||||
if (bond){
|
||||
SafeTransferLib.safeTransferFrom(
|
||||
token,
|
||||
_msgSender(),
|
||||
address(this),
|
||||
amount >> BOND_DIVISOR
|
||||
);
|
||||
} else if (merkleProof.length != 0) {
|
||||
// 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() ) {
|
||||
@ -178,7 +186,8 @@ contract P2PIX is BaseUtils {
|
||||
amount,
|
||||
token,
|
||||
_msgSender(),
|
||||
seller
|
||||
seller,
|
||||
bond
|
||||
);
|
||||
|
||||
_addLock(bal, l);
|
||||
@ -237,7 +246,7 @@ contract P2PIX is BaseUtils {
|
||||
SafeTransferLib.safeTransfer(
|
||||
t,
|
||||
l.buyerAddress,
|
||||
lockAmount
|
||||
l.bond ? lockAmount + lockAmount >> BOND_DIVISOR : lockAmount
|
||||
);
|
||||
|
||||
emit LockReleased(l.buyerAddress, lockID, lockAmount);
|
||||
|
@ -94,3 +94,9 @@ uint256 REPUTATION_LOWERBOUND
|
||||
uint256 LOCKAMOUNT_UPPERBOUND
|
||||
```
|
||||
|
||||
### BOND_DIVISOR
|
||||
|
||||
```solidity
|
||||
uint256 BOND_DIVISOR
|
||||
```
|
||||
|
||||
|
@ -13,6 +13,7 @@ struct Lock {
|
||||
contract ERC20 token;
|
||||
address buyerAddress;
|
||||
address seller;
|
||||
bool bond;
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -67,7 +67,7 @@ _Function sighash: 0x6d82d9e0_
|
||||
### lock
|
||||
|
||||
```solidity
|
||||
function lock(address seller, contract ERC20 token, uint80 amount, bytes32[] merkleProof, uint256[] expiredLocks) public returns (uint256 lockID)
|
||||
function lock(address seller, contract ERC20 token, uint80 amount, bytes32[] merkleProof, uint256[] expiredLocks, bool bond) public returns (uint256 lockID)
|
||||
```
|
||||
|
||||
Public method designed to lock an remaining amount of
|
||||
@ -78,7 +78,7 @@ 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
|
||||
There can only exist a lock per each `amount` partitioned
|
||||
from the total `remaining` value.
|
||||
Locks can only be performed in valid orders.
|
||||
|
||||
@ -93,6 +93,7 @@ _Function sighash: 0xdc43221c_
|
||||
| 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. |
|
||||
| bond | bool | |
|
||||
|
||||
#### Return Values
|
||||
|
||||
|
@ -615,6 +615,7 @@ describe("P2PIX", () => {
|
||||
price,
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
const fail2 = p2pix.lock(
|
||||
zero,
|
||||
@ -622,6 +623,7 @@ describe("P2PIX", () => {
|
||||
price,
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
|
||||
expect(fail).to.be.revertedWithCustomError(
|
||||
@ -651,6 +653,7 @@ describe("P2PIX", () => {
|
||||
price * 2n,
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
|
||||
await expect(fail).to.be.revertedWithCustomError(
|
||||
@ -676,6 +679,7 @@ describe("P2PIX", () => {
|
||||
1000n,
|
||||
[ethers.keccak256(ethers.toUtf8Bytes("wrong"))],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
|
||||
await expect(fail).to.be.revertedWithCustomError(
|
||||
@ -703,6 +707,7 @@ describe("P2PIX", () => {
|
||||
price * 2n,
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
|
||||
await expect(fail).to.be.revertedWithCustomError(
|
||||
@ -710,6 +715,42 @@ describe("P2PIX", () => {
|
||||
P2PixErrors.AmountNotAllowed,
|
||||
);
|
||||
});
|
||||
it("should override spend limit if buyer pays the bond", async () => {
|
||||
await erc20.approve(
|
||||
p2pix.address,
|
||||
price.mul(3),
|
||||
);
|
||||
await p2pix.deposit(
|
||||
"1",
|
||||
merkleRoot,
|
||||
erc20.address,
|
||||
price.mul(3),
|
||||
true,
|
||||
);
|
||||
await erc20
|
||||
.transfer(
|
||||
acc02.address,
|
||||
price,
|
||||
);
|
||||
await erc20
|
||||
.connect(acc02)
|
||||
.approve(
|
||||
p2pix.address,
|
||||
price.mul(30000),
|
||||
);
|
||||
const bond = p2pix
|
||||
.connect(acc02)
|
||||
.lock(
|
||||
owner.address,
|
||||
erc20.address,
|
||||
price.mul(2),
|
||||
[],
|
||||
[],
|
||||
true,
|
||||
);
|
||||
|
||||
await expect(bond).to.be.ok;
|
||||
});
|
||||
it("should create a lock, update storage and emit events via the allowlist path", async () => {
|
||||
const target = "333";
|
||||
await erc20.approve(p2pix.target, price);
|
||||
@ -728,6 +769,7 @@ describe("P2PIX", () => {
|
||||
price,
|
||||
proof,
|
||||
[],
|
||||
false,
|
||||
);
|
||||
const storage: Lock = await p2pix.mapLocks.staticCall(
|
||||
1,
|
||||
@ -772,6 +814,7 @@ describe("P2PIX", () => {
|
||||
price,
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
const storage: Lock = await p2pix.mapLocks.staticCall(
|
||||
1,
|
||||
@ -831,6 +874,7 @@ describe("P2PIX", () => {
|
||||
price,
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
await p2pix
|
||||
.connect(acc01)
|
||||
@ -847,6 +891,7 @@ describe("P2PIX", () => {
|
||||
price + 1n,
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
const storage: Lock = await p2pix.mapLocks.staticCall(
|
||||
2,
|
||||
@ -897,6 +942,7 @@ describe("P2PIX", () => {
|
||||
newPrice,
|
||||
proof,
|
||||
[],
|
||||
false,
|
||||
);
|
||||
const storage1: Lock = await p2pix.mapLocks.staticCall(
|
||||
1,
|
||||
@ -913,6 +959,7 @@ describe("P2PIX", () => {
|
||||
BigInt(100),
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
const storage2: Lock = await p2pix.mapLocks.staticCall(
|
||||
2,
|
||||
@ -929,6 +976,7 @@ describe("P2PIX", () => {
|
||||
BigInt(100),
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
const storage3: Lock = await p2pix.mapLocks.staticCall(
|
||||
3,
|
||||
@ -1205,6 +1253,7 @@ describe("P2PIX", () => {
|
||||
BigInt(100),
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
const lockID = BigInt(1);
|
||||
await mine(13);
|
||||
@ -1246,6 +1295,7 @@ describe("P2PIX", () => {
|
||||
BigInt(100),
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
const lockID = BigInt(1);
|
||||
await p2pix.release(
|
||||
@ -1290,6 +1340,7 @@ describe("P2PIX", () => {
|
||||
BigInt(100),
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
|
||||
await p2pix
|
||||
@ -1307,6 +1358,7 @@ describe("P2PIX", () => {
|
||||
BigInt(100),
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
const fail = p2pix
|
||||
.connect(acc01)
|
||||
@ -1348,6 +1400,7 @@ describe("P2PIX", () => {
|
||||
BigInt(100),
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
const fail = p2pix
|
||||
.connect(acc01)
|
||||
@ -1404,6 +1457,7 @@ describe("P2PIX", () => {
|
||||
BigInt(100),
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
const acc01Key = await p2pix._castAddrToKey.staticCall(
|
||||
acc01.address,
|
||||
@ -1568,6 +1622,7 @@ describe("P2PIX", () => {
|
||||
BigInt(100),
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
await p2pix
|
||||
.connect(acc03)
|
||||
@ -1577,6 +1632,7 @@ describe("P2PIX", () => {
|
||||
BigInt(50),
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
await p2pix
|
||||
.connect(acc03)
|
||||
@ -1586,6 +1642,7 @@ describe("P2PIX", () => {
|
||||
BigInt(25),
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
|
||||
const lockStatus1 =
|
||||
@ -1755,6 +1812,7 @@ describe("P2PIX", () => {
|
||||
BigInt(1),
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
const lockID = BigInt(1);
|
||||
const fail = p2pix.unlockExpired([lockID]);
|
||||
@ -1793,6 +1851,7 @@ describe("P2PIX", () => {
|
||||
BigInt(1),
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
const lockID = BigInt(1);
|
||||
// await mine(10);
|
||||
@ -1826,6 +1885,7 @@ describe("P2PIX", () => {
|
||||
BigInt(1),
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
);
|
||||
const lockID = BigInt(1);
|
||||
await mine(11);
|
||||
@ -1889,6 +1949,7 @@ describe("P2PIX", () => {
|
||||
price,
|
||||
proof,
|
||||
[],
|
||||
false,
|
||||
);
|
||||
// as return values of non view functions can't be accessed
|
||||
// outside the evm, we fetch the lockID from the emitted event.
|
||||
@ -1928,6 +1989,7 @@ describe("P2PIX", () => {
|
||||
BigInt(100),
|
||||
[],
|
||||
[lockID],
|
||||
false
|
||||
);
|
||||
const remaining = await p2pix.getBalance.staticCall(
|
||||
owner.address,
|
||||
@ -1961,6 +2023,7 @@ describe("P2PIX", () => {
|
||||
price,
|
||||
proof,
|
||||
[],
|
||||
false,
|
||||
);
|
||||
const lockID = BigInt(1);
|
||||
// mine blocks to expire lock
|
||||
|
Loading…
x
Reference in New Issue
Block a user