Replace bytes32 ids on deposits for uint256 counters.

This commit is contained in:
Filipe Soccol 2022-11-11 16:10:57 -03:00
parent 5c5327eedd
commit 67f9cbb9a7
5 changed files with 77 additions and 89 deletions

View File

@ -1,4 +1,4 @@
{ {
"_format": "hh-sol-dbg-1", "_format": "hh-sol-dbg-1",
"buildInfo": "../../build-info/fa666dddb19de15d02d4eaf695a7b974.json" "buildInfo": "../../build-info/7de52626ee9f8f66be6a4217c265b719.json"
} }

File diff suppressed because one or more lines are too long

View File

@ -3,13 +3,16 @@ pragma solidity ^0.8.9;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract P2PIX is Ownable { contract P2PIX is Ownable {
event DepositAdded(address indexed seller, bytes32 depositID, address token, uint256 premium, uint256 amount); using Counters for Counters.Counter;
event DepositClosed(address indexed seller, bytes32 depositID);
event DepositWithdrawn(address indexed seller, bytes32 depositID, uint256 amount); event DepositAdded(address indexed seller, uint256 depositID, address token, uint256 premium, uint256 amount);
event LockAdded(address indexed buyer, bytes32 indexed lockID, bytes32 depositID, uint256 amount); event DepositClosed(address indexed seller, uint256 depositID);
event DepositWithdrawn(address indexed seller, uint256 depositID, uint256 amount);
event LockAdded(address indexed buyer, bytes32 indexed lockID, uint256 depositID, uint256 amount);
event LockReleased(address indexed buyer, bytes32 lockId); event LockReleased(address indexed buyer, bytes32 lockId);
event LockReturned(address indexed buyer, bytes32 lockId); event LockReturned(address indexed buyer, bytes32 lockId);
// Events // Events
@ -25,7 +28,7 @@ contract P2PIX is Ownable {
} }
struct Lock { struct Lock {
bytes32 depositID; uint256 depositID;
address targetAddress; // Where goes the tokens when validated address targetAddress; // Where goes the tokens when validated
address relayerAddress; // Relayer address that facilitated this transaction address relayerAddress; // Relayer address that facilitated this transaction
uint256 relayerPremium; // Amount to be paid for relayer uint256 relayerPremium; // Amount to be paid for relayer
@ -33,19 +36,20 @@ contract P2PIX is Ownable {
uint256 expirationBlock; // If not paid at this block will be expired uint256 expirationBlock; // If not paid at this block will be expired
} }
Counters.Counter public depositCount;
// Default blocks that lock will hold tokens // Default blocks that lock will hold tokens
uint256 public defaultLockBlocks; uint256 public defaultLockBlocks;
// List of valid Bacen signature addresses // List of valid Bacen signature addresses
mapping(address => bool) public validBacenSigners; mapping(address => bool) public validBacenSigners;
// Seller list of deposits // Seller list of deposits
mapping(bytes32 => Deposit) mapDeposits; mapping(uint256 => Deposit) mapDeposits;
// List of Locks // List of Locks
mapping(bytes32 => Lock) mapLocks; mapping(bytes32 => Lock) mapLocks;
// List of Pix transactions already signed // List of Pix transactions already signed
mapping(bytes32 => bool) usedTransactions; mapping(bytes32 => bool) usedTransactions;
modifier onlySeller(bytes32 depositID) { modifier onlySeller(uint256 depositID) {
require(mapDeposits[depositID].seller == msg.sender, "P2PIX: Only seller could call this function."); require(mapDeposits[depositID].seller == msg.sender, "P2PIX: Only seller could call this function.");
_; _;
} }
@ -62,18 +66,19 @@ contract P2PIX is Ownable {
address token, address token,
uint256 amount, uint256 amount,
string calldata pixTarget string calldata pixTarget
) public payable returns (bytes32 depositID){ ) public payable returns (uint256 depositID){
depositID = keccak256(abi.encodePacked(pixTarget, amount)); depositID = depositCount.current();
require(!mapDeposits[depositID].valid, 'P2PIX: Deposit already exist and it is still valid'); require(!mapDeposits[depositID].valid, 'P2PIX: Deposit already exist and it is still valid');
IERC20 t = IERC20(token); IERC20 t = IERC20(token);
t.transferFrom(msg.sender, address(this), amount); t.transferFrom(msg.sender, address(this), amount);
Deposit memory d = Deposit(msg.sender, token, amount, msg.value, true, pixTarget); Deposit memory d = Deposit(msg.sender, token, amount, msg.value, true, pixTarget);
mapDeposits[depositID] = d; mapDeposits[depositID] = d;
depositCount.increment();
emit DepositAdded(msg.sender, depositID, token, msg.value, amount); emit DepositAdded(msg.sender, depositID, token, msg.value, amount);
} }
// Vendedor pode invalidar da ordem de venda impedindo novos locks na mesma (isso não afeta nenhum lock que esteja ativo). // 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) { function cancelDeposit(uint256 depositID) public onlySeller(depositID) {
mapDeposits[depositID].valid = false; mapDeposits[depositID].valid = false;
emit DepositClosed(mapDeposits[depositID].seller, depositID); emit DepositClosed(mapDeposits[depositID].seller, depositID);
} }
@ -85,7 +90,7 @@ contract P2PIX is Ownable {
// Essa etapa pode ser feita pelo vendedor conjuntamente com a parte 1. // Essa etapa pode ser feita pelo vendedor conjuntamente com a parte 1.
// Retorna um LockID. // Retorna um LockID.
function lock( function lock(
bytes32 depositID, uint256 depositID,
address targetAddress, address targetAddress,
address relayerAddress, address relayerAddress,
uint256 relayerPremium, uint256 relayerPremium,
@ -159,7 +164,7 @@ contract P2PIX is Ownable {
// Após os locks expirarem, vendedor pode interagir c/ o contrato e recuperar os tokens de um depósito específico. // Após os locks expirarem, vendedor pode interagir c/ o contrato e recuperar os tokens de um depósito específico.
function withdraw( function withdraw(
bytes32 depositID, uint256 depositID,
bytes32[] calldata expiredLocks bytes32[] calldata expiredLocks
) public onlySeller(depositID) { ) public onlySeller(depositID) {
unlockExpired(expiredLocks); unlockExpired(expiredLocks);

View File

@ -6,7 +6,6 @@ describe("P2PIX deposit test", function () {
let owner, wallet2, wallet3, wallet4; let owner, wallet2, wallet3, wallet4;
let p2pix; // Contract instance let p2pix; // Contract instance
let erc20; // Token instance let erc20; // Token instance
let depositID;
it("Will deploy contracts", async function () { it("Will deploy contracts", async function () {
@ -30,11 +29,11 @@ describe("P2PIX deposit test", function () {
it("Should allow create a deposit", async function () { it("Should allow create a deposit", async function () {
let transaction = await erc20.approve(p2pix.address,ethers.utils.parseEther('1000')); let transaction = await erc20.approve(p2pix.address,ethers.utils.parseEther('2000'));
await expect(transaction).to.emit(erc20, 'Approval').withArgs( await expect(transaction).to.emit(erc20, 'Approval').withArgs(
owner.address, owner.address,
p2pix.address, p2pix.address,
ethers.utils.parseEther('1000') ethers.utils.parseEther('2000')
) )
transaction = await p2pix.deposit( transaction = await p2pix.deposit(
@ -43,72 +42,44 @@ describe("P2PIX deposit test", function () {
'SELLER PIX KEY', 'SELLER PIX KEY',
{value:ethers.utils.parseEther('0.1')} {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( await expect(transaction).to.emit(p2pix, 'DepositAdded').withArgs(
owner.address, owner.address,
depositID, 0,
erc20.address, erc20.address,
ethers.utils.parseEther('0.1'), ethers.utils.parseEther('0.1'),
ethers.utils.parseEther('1000') ethers.utils.parseEther('1000')
) )
}) })
it("Should prevent create same deposit", async function () { it("Should allow create second 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( transaction = await p2pix.deposit(
erc20.address, erc20.address,
ethers.utils.parseEther('1000'), ethers.utils.parseEther('1000'),
'SELLER PIX KEY', 'SELLER PIX KEY',
{value:ethers.utils.parseEther('0.1')} {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( await expect(transaction).to.emit(p2pix, 'DepositAdded').withArgs(
owner.address, owner.address,
depositID, 1,
erc20.address, erc20.address,
ethers.utils.parseEther('0.1'), ethers.utils.parseEther('0.1'),
ethers.utils.parseEther('1000') ethers.utils.parseEther('1000')
) )
}) })
it("Should allow cancel the deposit again", async function () { it("Should allow cancel first deposit", async function () {
const transaction = await p2pix.cancelDeposit(depositID); const transaction = await p2pix.cancelDeposit(0);
await expect(transaction).to.emit(p2pix, 'DepositClosed').withArgs( await expect(transaction).to.emit(p2pix, 'DepositClosed').withArgs(
owner.address, owner.address,
depositID 0
) )
}) })
it("Should allow withdraw the deposit", async function () { it("Should allow withdraw the deposit", async function () {
const transaction = await p2pix.withdraw(depositID, []); const transaction = await p2pix.withdraw(0, []);
await expect(transaction).to.emit(p2pix, 'DepositWithdrawn').withArgs( await expect(transaction).to.emit(p2pix, 'DepositWithdrawn').withArgs(
owner.address, owner.address,
depositID, 0,
ethers.utils.parseEther('1000') ethers.utils.parseEther('1000')
) )
}) })

View File

@ -6,7 +6,7 @@ describe("P2PIX lock/release test", function () {
let owner, wallet2, wallet3, wallet4; let owner, wallet2, wallet3, wallet4;
let p2pix; // Contract instance let p2pix; // Contract instance
let erc20; // Token instance let erc20; // Token instance
let depositID, lockID; let lockID;
it("Will deploy contracts", async function () { it("Will deploy contracts", async function () {
@ -44,10 +44,9 @@ describe("P2PIX lock/release test", function () {
'SELLER PIX KEY', 'SELLER PIX KEY',
{value:ethers.utils.parseEther('0.1')} {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( await expect(transaction).to.emit(p2pix, 'DepositAdded').withArgs(
owner.address, owner.address,
depositID, 0,
erc20.address, erc20.address,
ethers.utils.parseEther('0.1'), ethers.utils.parseEther('0.1'),
ethers.utils.parseEther('1000') ethers.utils.parseEther('1000')
@ -57,22 +56,22 @@ describe("P2PIX lock/release test", function () {
it("Should allow create a new lock", async function () { it("Should allow create a new lock", async function () {
transaction = await p2pix.connect(wallet3).lock( transaction = await p2pix.connect(wallet3).lock(
depositID, 0,
wallet3.address, wallet3.address,
ethers.constants.AddressZero, ethers.constants.AddressZero,
'0', '0',
ethers.utils.parseEther('100'), ethers.utils.parseEther('100'),
[] []
) )
lockID = ethers.utils.solidityKeccak256(['bytes32', 'uint256', 'address'], [ lockID = ethers.utils.solidityKeccak256(['uint256', 'uint256', 'address'], [
depositID, 0,
ethers.utils.parseEther('100'), ethers.utils.parseEther('100'),
wallet3.address wallet3.address
]) ])
await expect(transaction).to.emit(p2pix, 'LockAdded').withArgs( await expect(transaction).to.emit(p2pix, 'LockAdded').withArgs(
wallet3.address, wallet3.address,
lockID, lockID,
depositID, 0,
ethers.utils.parseEther('100') ethers.utils.parseEther('100')
) )
console.log('GAS USED:', (await transaction.wait()).cumulativeGasUsed.toString()) console.log('GAS USED:', (await transaction.wait()).cumulativeGasUsed.toString())
@ -117,29 +116,29 @@ describe("P2PIX lock/release test", function () {
it("Should allow recreate same lock", async function () { it("Should allow recreate same lock", async function () {
transaction = await p2pix.connect(wallet3).lock( transaction = await p2pix.connect(wallet3).lock(
depositID, 0,
wallet3.address, wallet3.address,
ethers.constants.AddressZero, ethers.constants.AddressZero,
'0', '0',
ethers.utils.parseEther('100'), ethers.utils.parseEther('100'),
[] []
) )
lockID = ethers.utils.solidityKeccak256(['bytes32', 'uint256', 'address'], [ lockID = ethers.utils.solidityKeccak256(['uint256', 'uint256', 'address'], [
depositID, 0,
ethers.utils.parseEther('100'), ethers.utils.parseEther('100'),
wallet3.address wallet3.address
]) ])
await expect(transaction).to.emit(p2pix, 'LockAdded').withArgs( await expect(transaction).to.emit(p2pix, 'LockAdded').withArgs(
wallet3.address, wallet3.address,
lockID, lockID,
depositID, 0,
ethers.utils.parseEther('100'), ethers.utils.parseEther('100'),
) )
}) })
it("Should prevent create again same lock", async function () { it("Should prevent create again same lock", async function () {
await expect(p2pix.connect(wallet3).lock( await expect(p2pix.connect(wallet3).lock(
depositID, 0,
wallet3.address, wallet3.address,
ethers.constants.AddressZero, ethers.constants.AddressZero,
'0', '0',
@ -187,9 +186,9 @@ describe("P2PIX lock/release test", function () {
)).to.be.revertedWith('P2PIX: Lock already released or returned'); )).to.be.revertedWith('P2PIX: Lock already released or returned');
}) })
it("Should prevent create a 800 lock", async function () { it("Should prevent create a 900 lock", async function () {
await expect(p2pix.connect(wallet3).lock( await expect(p2pix.connect(wallet3).lock(
depositID, 0,
wallet3.address, wallet3.address,
ethers.constants.AddressZero, ethers.constants.AddressZero,
'0', '0',
@ -200,22 +199,22 @@ describe("P2PIX lock/release test", function () {
it("Should allow recreate same lock again", async function () { it("Should allow recreate same lock again", async function () {
transaction = await p2pix.connect(wallet3).lock( transaction = await p2pix.connect(wallet3).lock(
depositID, 0,
wallet3.address, wallet3.address,
ethers.constants.AddressZero, ethers.constants.AddressZero,
'0', '0',
ethers.utils.parseEther('100'), ethers.utils.parseEther('100'),
[] []
) )
lockID = ethers.utils.solidityKeccak256(['bytes32', 'uint256', 'address'], [ lockID = ethers.utils.solidityKeccak256(['uint256', 'uint256', 'address'], [
depositID, 0,
ethers.utils.parseEther('100'), ethers.utils.parseEther('100'),
wallet3.address wallet3.address
]) ])
await expect(transaction).to.emit(p2pix, 'LockAdded').withArgs( await expect(transaction).to.emit(p2pix, 'LockAdded').withArgs(
wallet3.address, wallet3.address,
lockID, lockID,
depositID, 0,
ethers.utils.parseEther('100') ethers.utils.parseEther('100')
) )
}) })