bond to override lock limit

This commit is contained in:
hueso 2024-03-03 21:58:41 -03:00
parent e57428525b
commit b2198306e6
7 changed files with 91 additions and 9 deletions

View File

@ -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%
}

View File

@ -13,6 +13,7 @@ library DataTypes {
ERC20 token;
address buyerAddress;
address seller;
bool bond;
}
// prettier-ignore

View File

@ -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);
// transaction forwarding must leave `merkleProof` empty;
// otherwise, the trustedForwarder must be previously added
// to a seller whitelist.
if (merkleProof.length != 0) {
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.
_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);

View File

@ -94,3 +94,9 @@ uint256 REPUTATION_LOWERBOUND
uint256 LOCKAMOUNT_UPPERBOUND
```
### BOND_DIVISOR
```solidity
uint256 BOND_DIVISOR
```

View File

@ -13,6 +13,7 @@ struct Lock {
contract ERC20 token;
address buyerAddress;
address seller;
bool bond;
}
```

View File

@ -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

View File

@ -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