Merge pull request #326 from status-im/feat/send-fees
Send fees to the arbiter and /or the Staking pool
This commit is contained in:
commit
512cb7f5ec
|
@ -50,7 +50,7 @@ contract Escrow is Pausable, MessageSigned, Fees, Arbitrable, RelayRecipient {
|
||||||
TradeType tradeType;
|
TradeType tradeType;
|
||||||
EscrowStatus status;
|
EscrowStatus status;
|
||||||
address payable buyer;
|
address payable buyer;
|
||||||
address arbitrator;
|
address payable arbitrator;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TradeType {FIAT, CRYPTO}
|
enum TradeType {FIAT, CRYPTO}
|
||||||
|
@ -180,7 +180,7 @@ contract Escrow is Pausable, MessageSigned, Fees, Arbitrable, RelayRecipient {
|
||||||
if (token != address(0)) {
|
if (token != address(0)) {
|
||||||
require(msg.value == 0, "Cannot send ETH with token address different from 0");
|
require(msg.value == 0, "Cannot send ETH with token address different from 0");
|
||||||
ERC20Token erc20token = ERC20Token(token);
|
ERC20Token erc20token = ERC20Token(token);
|
||||||
require(erc20token.transferFrom(_from, address(this), _tokenAmount), "Unsuccessful token transfer");
|
require(erc20token.transferFrom(_from, address(this), _tokenAmount), "Unsuccessful token transfer fund");
|
||||||
}
|
}
|
||||||
payFee(_from, _escrowId, _tokenAmount, token);
|
payFee(_from, _escrowId, _tokenAmount, token);
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ contract Escrow is Pausable, MessageSigned, Fees, Arbitrable, RelayRecipient {
|
||||||
uint _assetPrice
|
uint _assetPrice
|
||||||
) internal returns(uint escrowId) {
|
) internal returns(uint escrowId) {
|
||||||
address seller;
|
address seller;
|
||||||
address arbitrator;
|
address payable arbitrator;
|
||||||
bool deleted;
|
bool deleted;
|
||||||
|
|
||||||
(,,,,seller, arbitrator, deleted) = metadataStore.offer(_offerId);
|
(,,,,seller, arbitrator, deleted) = metadataStore.offer(_offerId);
|
||||||
|
@ -257,7 +257,7 @@ contract Escrow is Pausable, MessageSigned, Fees, Arbitrable, RelayRecipient {
|
||||||
EscrowStatus mStatus = transactions[_escrowId].status;
|
EscrowStatus mStatus = transactions[_escrowId].status;
|
||||||
require(metadataStore.getOfferOwner(transactions[_escrowId].offerId) == get_sender(), "Only the seller can release the escrow");
|
require(metadataStore.getOfferOwner(transactions[_escrowId].offerId) == get_sender(), "Only the seller can release the escrow");
|
||||||
require(mStatus == EscrowStatus.PAID || mStatus == EscrowStatus.FUNDED, "Invalid transaction status");
|
require(mStatus == EscrowStatus.PAID || mStatus == EscrowStatus.FUNDED, "Invalid transaction status");
|
||||||
_release(_escrowId, transactions[_escrowId]);
|
_release(_escrowId, transactions[_escrowId], false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -265,16 +265,16 @@ contract Escrow is Pausable, MessageSigned, Fees, Arbitrable, RelayRecipient {
|
||||||
* @param _escrowId Id of the escrow
|
* @param _escrowId Id of the escrow
|
||||||
* @param trx EscrowTransaction with data of transaction to be released
|
* @param trx EscrowTransaction with data of transaction to be released
|
||||||
*/
|
*/
|
||||||
function _release(uint _escrowId, EscrowTransaction storage trx) internal {
|
function _release(uint _escrowId, EscrowTransaction storage trx, bool isDispute) internal {
|
||||||
trx.status = EscrowStatus.RELEASED;
|
trx.status = EscrowStatus.RELEASED;
|
||||||
|
|
||||||
address token = metadataStore.getAsset(trx.offerId);
|
address token = metadataStore.getAsset(trx.offerId);
|
||||||
if(token == address(0)){
|
if(token == address(0)){
|
||||||
trx.buyer.transfer(trx.tokenAmount); // TODO: transfer fee to Status?
|
trx.buyer.transfer(trx.tokenAmount);
|
||||||
} else {
|
} else {
|
||||||
ERC20Token erc20token = ERC20Token(token);
|
require(ERC20Token(token).transfer(trx.buyer, trx.tokenAmount), "Couldn't transfer funds");
|
||||||
require(erc20token.transfer(trx.buyer, trx.tokenAmount), "Couldn't transfer funds");
|
|
||||||
}
|
}
|
||||||
|
releaseFee(trx.arbitrator, trx.tokenAmount, token, isDispute);
|
||||||
|
|
||||||
emit Released(_escrowId, block.timestamp);
|
emit Released(_escrowId, block.timestamp);
|
||||||
}
|
}
|
||||||
|
@ -362,7 +362,7 @@ contract Escrow is Pausable, MessageSigned, Fees, Arbitrable, RelayRecipient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_cancel(_escrowId, seller, trx);
|
_cancel(_escrowId, seller, trx, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -370,10 +370,15 @@ contract Escrow is Pausable, MessageSigned, Fees, Arbitrable, RelayRecipient {
|
||||||
* @param _escrowId Id of the escrow
|
* @param _escrowId Id of the escrow
|
||||||
* @param trx EscrowTransaction with details of transaction to be marked as canceled
|
* @param trx EscrowTransaction with details of transaction to be marked as canceled
|
||||||
*/
|
*/
|
||||||
function _cancel(uint _escrowId, address payable _seller, EscrowTransaction storage trx) internal {
|
function _cancel(uint _escrowId, address payable _seller, EscrowTransaction storage trx, bool isDispute) internal {
|
||||||
if(trx.status == EscrowStatus.FUNDED){
|
if(trx.status == EscrowStatus.FUNDED){
|
||||||
address token = metadataStore.getAsset(trx.offerId);
|
address token = metadataStore.getAsset(trx.offerId);
|
||||||
uint amount = trx.tokenAmount + getFeeFromAmount(trx.tokenAmount);
|
uint amount;
|
||||||
|
if (isDispute) {
|
||||||
|
amount = trx.tokenAmount;
|
||||||
|
} else {
|
||||||
|
amount = trx.tokenAmount + getValueOffMillipercent(trx.tokenAmount, feeMilliPercent);
|
||||||
|
}
|
||||||
if(token == address(0)){
|
if(token == address(0)){
|
||||||
_seller.transfer(amount);
|
_seller.transfer(amount);
|
||||||
} else {
|
} else {
|
||||||
|
@ -398,7 +403,7 @@ contract Escrow is Pausable, MessageSigned, Fees, Arbitrable, RelayRecipient {
|
||||||
require(trx.status == EscrowStatus.FUNDED, "Cannot withdraw from escrow in a stage different from FUNDED. Open a case");
|
require(trx.status == EscrowStatus.FUNDED, "Cannot withdraw from escrow in a stage different from FUNDED. Open a case");
|
||||||
|
|
||||||
address payable seller = metadataStore.getOfferOwner(trx.offerId);
|
address payable seller = metadataStore.getOfferOwner(trx.offerId);
|
||||||
_cancel(_escrowId, seller, trx);
|
_cancel(_escrowId, seller, trx, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -481,9 +486,10 @@ contract Escrow is Pausable, MessageSigned, Fees, Arbitrable, RelayRecipient {
|
||||||
require(trx.buyer != _arbitrator && seller != _arbitrator, "Arbitrator cannot be part of transaction");
|
require(trx.buyer != _arbitrator && seller != _arbitrator, "Arbitrator cannot be part of transaction");
|
||||||
|
|
||||||
if(_releaseFunds){
|
if(_releaseFunds){
|
||||||
_release(_escrowId, trx);
|
_release(_escrowId, trx, true);
|
||||||
} else {
|
} else {
|
||||||
_cancel(_escrowId, seller, trx);
|
_cancel(_escrowId, seller, trx, true);
|
||||||
|
releaseFee(trx.arbitrator, trx.tokenAmount, metadataStore.getAsset(trx.offerId), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ contract Fees is Ownable {
|
||||||
event FeeDestinationChanged(address payable);
|
event FeeDestinationChanged(address payable);
|
||||||
event FeeMilliPercentChanged(uint amount);
|
event FeeMilliPercentChanged(uint amount);
|
||||||
event FeesWithdrawn(uint amount, address token);
|
event FeesWithdrawn(uint amount, address token);
|
||||||
event MyEvent(uint fees, address destination, uint balance);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param _feeDestination Address to send the fees once withdraw is called
|
* @param _feeDestination Address to send the fees once withdraw is called
|
||||||
|
@ -51,26 +50,42 @@ contract Fees is Ownable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @notice Withdraw fees by sending them to the fee destination address
|
* @notice Release fee to fee destination and arbitrator
|
||||||
*/
|
* @param _arbitrator Arbitrator address to transfer fee to
|
||||||
function withdrawFees(address _tokenAddress) public {
|
* @param _value Value sold in the escrow
|
||||||
uint fees = feeTokenBalances[_tokenAddress];
|
* @param _isDispute Boolean telling if it was from a dispute. With a dispute, the arbitrator gets more
|
||||||
feeTokenBalances[_tokenAddress] = 0;
|
*/
|
||||||
if (_tokenAddress == address(0)) {
|
function releaseFee(address payable _arbitrator, uint _value, address _tokenAddress, bool _isDispute) internal {
|
||||||
require(address(this).balance >= fees, "Not enough balance");
|
uint _milliPercentToArbitrator;
|
||||||
feeDestination.transfer(fees);
|
if (_isDispute) {
|
||||||
emit MyEvent(fees, feeDestination, address(this).balance);
|
_milliPercentToArbitrator = 100000; // 100%
|
||||||
} else {
|
} else {
|
||||||
ERC20Token tokenToWithdraw = ERC20Token(_tokenAddress);
|
_milliPercentToArbitrator = 10000; // 10%
|
||||||
require(tokenToWithdraw.transfer(feeDestination, fees), "Error transferring fees");
|
}
|
||||||
|
|
||||||
|
uint feeAmount = getValueOffMillipercent(_value, feeMilliPercent);
|
||||||
|
uint arbitratorValue = getValueOffMillipercent(feeAmount, _milliPercentToArbitrator);
|
||||||
|
uint destinationValue = feeAmount - arbitratorValue;
|
||||||
|
|
||||||
|
if (_tokenAddress != address(0)) {
|
||||||
|
ERC20Token tokenToPay = ERC20Token(_tokenAddress);
|
||||||
|
// Arbitrator transfer
|
||||||
|
require(tokenToPay.transfer(_arbitrator, arbitratorValue), "Unsuccessful token transfer abri");
|
||||||
|
if (destinationValue > 0) {
|
||||||
|
require(tokenToPay.transfer(feeDestination, destinationValue), "Unsuccessful token transfer destination");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_arbitrator.transfer(arbitratorValue);
|
||||||
|
if (destinationValue > 0) {
|
||||||
|
feeDestination.transfer(destinationValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
emit FeesWithdrawn(fees, _tokenAddress);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFeeFromAmount(uint _value) internal returns(uint) {
|
function getValueOffMillipercent(uint _value, uint _milliPercent) internal returns(uint) {
|
||||||
// To get the factor, we divide like 100 like a normal percent, but we multiply that by 1000 because it's a milliPercent
|
// To get the factor, we divide like 100 like a normal percent, but we multiply that by 1000 because it's a milliPercent
|
||||||
// Eg: 1 % = 1000 millipercent => Factor is 0.01, so 1000 divided by 100 * 1000
|
// Eg: 1 % = 1000 millipercent => Factor is 0.01, so 1000 divided by 100 * 1000
|
||||||
return (_value * feeMilliPercent) / (100 * 1000);
|
return (_value * _milliPercent) / (100 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,12 +100,12 @@ contract Fees is Ownable {
|
||||||
if (feePaid[_id]) return;
|
if (feePaid[_id]) return;
|
||||||
|
|
||||||
feePaid[_id] = true;
|
feePaid[_id] = true;
|
||||||
uint feeAmount = getFeeFromAmount(_value);
|
uint feeAmount = getValueOffMillipercent(_value, feeMilliPercent);
|
||||||
feeTokenBalances[_tokenAddress] += feeAmount;
|
feeTokenBalances[_tokenAddress] += feeAmount;
|
||||||
|
|
||||||
if (_tokenAddress != address(0)) {
|
if (_tokenAddress != address(0)) {
|
||||||
ERC20Token tokenToPay = ERC20Token(_tokenAddress);
|
ERC20Token tokenToPay = ERC20Token(_tokenAddress);
|
||||||
require(tokenToPay.transferFrom(_from, address(this), feeAmount), "Unsuccessful token transfer");
|
require(tokenToPay.transferFrom(_from, address(this), feeAmount), "Unsuccessful token transfer pay fee");
|
||||||
} else {
|
} else {
|
||||||
require(msg.value == (_value + feeAmount), "ETH amount is required");
|
require(msg.value == (_value + feeAmount), "ETH amount is required");
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ contract MetadataStore is MessageSigned {
|
||||||
address asset;
|
address asset;
|
||||||
string currency;
|
string currency;
|
||||||
address payable owner;
|
address payable owner;
|
||||||
address arbitrator;
|
address payable arbitrator;
|
||||||
bool deleted;
|
bool deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,12 +161,12 @@ contract MetadataStore is MessageSigned {
|
||||||
uint _nonce
|
uint _nonce
|
||||||
) public returns(address payable _user) {
|
) public returns(address payable _user) {
|
||||||
_user = address(uint160(getSigner(_username, _statusContactCode, _nonce, _signature)));
|
_user = address(uint160(getSigner(_username, _statusContactCode, _nonce, _signature)));
|
||||||
|
|
||||||
require(_nonce == user_nonce[_user], "Invalid nonce");
|
require(_nonce == user_nonce[_user], "Invalid nonce");
|
||||||
|
|
||||||
user_nonce[_user]++;
|
user_nonce[_user]++;
|
||||||
_addOrUpdateUser(_user, _statusContactCode, _location, _username);
|
_addOrUpdateUser(_user, _statusContactCode, _location, _username);
|
||||||
|
|
||||||
return _user;
|
return _user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ contract MetadataStore is MessageSigned {
|
||||||
string memory _username,
|
string memory _username,
|
||||||
PaymentMethods[] memory _paymentMethods,
|
PaymentMethods[] memory _paymentMethods,
|
||||||
int8 _margin,
|
int8 _margin,
|
||||||
address _arbitrator
|
address payable _arbitrator
|
||||||
) public {
|
) public {
|
||||||
require(sellingLicenses.isLicenseOwner(msg.sender), "Not a license owner");
|
require(sellingLicenses.isLicenseOwner(msg.sender), "Not a license owner");
|
||||||
require(arbitrationLicenses.isLicenseOwner(_arbitrator), "Not an arbitrator");
|
require(arbitrationLicenses.isLicenseOwner(_arbitrator), "Not an arbitrator");
|
||||||
|
@ -267,7 +267,7 @@ contract MetadataStore is MessageSigned {
|
||||||
int8 margin,
|
int8 margin,
|
||||||
PaymentMethods[] memory paymentMethods,
|
PaymentMethods[] memory paymentMethods,
|
||||||
address payable owner,
|
address payable owner,
|
||||||
address arbitrator,
|
address payable arbitrator,
|
||||||
bool deleted
|
bool deleted
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
|
@ -307,7 +307,7 @@ contract MetadataStore is MessageSigned {
|
||||||
* @param _id Offer id
|
* @param _id Offer id
|
||||||
* @return Arbitrator address
|
* @return Arbitrator address
|
||||||
*/
|
*/
|
||||||
function getArbitrator(uint256 _id) public view returns (address) {
|
function getArbitrator(uint256 _id) public view returns (address payable) {
|
||||||
return (offers[_id].arbitrator);
|
return (offers[_id].arbitrator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,6 +164,22 @@
|
||||||
"0x243b1fc854f17cfe515881f5d2fa88d13e335761be7ff309a3bcbda85c5c0657": {
|
"0x243b1fc854f17cfe515881f5d2fa88d13e335761be7ff309a3bcbda85c5c0657": {
|
||||||
"name": "Escrow",
|
"name": "Escrow",
|
||||||
"address": "0x6b0Fe7fD0195617d611D4d7C48Fc9B084c66Ab0F"
|
"address": "0x6b0Fe7fD0195617d611D4d7C48Fc9B084c66Ab0F"
|
||||||
|
},
|
||||||
|
"0x7dcace6b87f6fdb9bbc007f97935903616540920c6e2ad29d775da0ad92f5ba6": {
|
||||||
|
"name": "SellerLicense",
|
||||||
|
"address": "0x587c8B39e9b93e157aA6868FBF026eadcD092806"
|
||||||
|
},
|
||||||
|
"0x875d12c948438b63284354c3f5b5bb3868124e3adbb7b30a2d999ffda8fd59ed": {
|
||||||
|
"name": "ArbitrationLicense",
|
||||||
|
"address": "0x7DeECdA728F9291fEee06a8141e84b26B5bb0496"
|
||||||
|
},
|
||||||
|
"0x46e306e5174128c9c45ae57df1f61547469fcc4601fd5d7051658427ca1d74a9": {
|
||||||
|
"name": "MetadataStore",
|
||||||
|
"address": "0xaA4Bcf44B00dA7Bb43522b21b54dAE9CB82634E4"
|
||||||
|
},
|
||||||
|
"0xf60e5d23e992bee7f624b9d45b5aa8649119c0175948eef360e5759b33fac38c": {
|
||||||
|
"name": "Escrow",
|
||||||
|
"address": "0xb15C531dc6284E566e0010B458CEb4039bfdf175"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -584,7 +584,7 @@ export const Tokens = {
|
||||||
{
|
{
|
||||||
symbol: 'SNT',
|
symbol: 'SNT',
|
||||||
name: "Status Network Token",
|
name: "Status Network Token",
|
||||||
address: SNT.address.toLowerCase(),
|
address: SNT.address && SNT.address.toLowerCase(),
|
||||||
decimals: 18
|
decimals: 18
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -596,13 +596,13 @@ export const Tokens = {
|
||||||
{
|
{
|
||||||
symbol: 'DAI',
|
symbol: 'DAI',
|
||||||
name: 'DAI',
|
name: 'DAI',
|
||||||
address: DAI.address.toLowerCase(),
|
address: DAI.address && DAI.address.toLowerCase(),
|
||||||
decimals: 18
|
decimals: 18
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
symbol: 'MKR',
|
symbol: 'MKR',
|
||||||
name: "MKR",
|
name: "MKR",
|
||||||
address: MKR.address.toLowerCase(),
|
address: MKR.address && MKR.address.toLowerCase(),
|
||||||
decimals: 18
|
decimals: 18
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
@ -87,7 +87,7 @@ contract("Escrow", function() {
|
||||||
|
|
||||||
const {toBN} = web3.utils;
|
const {toBN} = web3.utils;
|
||||||
|
|
||||||
const tradeAmount = 100;
|
const tradeAmount = 1000000;
|
||||||
const feeAmount = Math.round(tradeAmount * (feePercent / 100));
|
const feeAmount = Math.round(tradeAmount * (feePercent / 100));
|
||||||
|
|
||||||
// util
|
// util
|
||||||
|
@ -250,8 +250,7 @@ contract("Escrow", function() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("A seller can cancel their ETH escrows", async () => {
|
it("A seller can cancel their expired ETH escrows", async () => {
|
||||||
await StandardToken.methods.approve(Escrow.options.address, feeAmount).send({from: accounts[0]});
|
|
||||||
receipt = await Escrow.methods.create_and_fund(accounts[1], ethOfferId, tradeAmount, expirationTime, FIAT, 140).send({from: accounts[0], value: tradeAmount + feeAmount});
|
receipt = await Escrow.methods.create_and_fund(accounts[1], ethOfferId, tradeAmount, expirationTime, FIAT, 140).send({from: accounts[0], value: tradeAmount + feeAmount});
|
||||||
created = receipt.events.Created;
|
created = receipt.events.Created;
|
||||||
escrowId = created.returnValues.escrowId;
|
escrowId = created.returnValues.escrowId;
|
||||||
|
@ -267,7 +266,7 @@ contract("Escrow", function() {
|
||||||
assert.equal(escrow.status, ESCROW_CANCELED, "Should have been canceled");
|
assert.equal(escrow.status, ESCROW_CANCELED, "Should have been canceled");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("A seller can cancel their token escrows", async () => {
|
it("A seller can cancel their expired token escrows and gets back the fee", async () => {
|
||||||
await StandardToken.methods.mint(accounts[0], tradeAmount + feeAmount).send();
|
await StandardToken.methods.mint(accounts[0], tradeAmount + feeAmount).send();
|
||||||
await StandardToken.methods.approve(Escrow.options.address, tradeAmount + feeAmount).send({from: accounts[0]});
|
await StandardToken.methods.approve(Escrow.options.address, tradeAmount + feeAmount).send({from: accounts[0]});
|
||||||
|
|
||||||
|
@ -409,7 +408,8 @@ contract("Escrow", function() {
|
||||||
const contractBalanceAfterEscrow = await StandardToken.methods.balanceOf(Escrow.options.address).call();
|
const contractBalanceAfterEscrow = await StandardToken.methods.balanceOf(Escrow.options.address).call();
|
||||||
|
|
||||||
assert.equal(toBN(escrow.tokenAmount).add(toBN(buyerBalanceBeforeEscrow)), buyerBalanceAfterEscrow, "Invalid buyer balance");
|
assert.equal(toBN(escrow.tokenAmount).add(toBN(buyerBalanceBeforeEscrow)), buyerBalanceAfterEscrow, "Invalid buyer balance");
|
||||||
assert.equal(contractBalanceAfterEscrow, toBN(contractBalanceBeforeEscrow).sub(toBN(tradeAmount)), "Invalid contract balance");
|
const after = toBN(contractBalanceBeforeEscrow).sub(toBN(tradeAmount).add(toBN(feeAmount)));
|
||||||
|
assert.equal(contractBalanceAfterEscrow, after, "Invalid contract balance");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Released escrow cannot be released again", async() => {
|
it("Released escrow cannot be released again", async() => {
|
||||||
|
@ -743,13 +743,17 @@ contract("Escrow", function() {
|
||||||
assert.strictEqual(arbitrationCanceled.returnValues.escrowId, escrowId, "Invalid escrowId");
|
assert.strictEqual(arbitrationCanceled.returnValues.escrowId, escrowId, "Invalid escrowId");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should transfer to buyer if case is solved in their favor", async() => {
|
it("should transfer to buyer if case is solved in their favor and the fee goes to arbitrator", async() => {
|
||||||
|
const arbitratorBalanceBefore = await web3.eth.getBalance(arbitrator);
|
||||||
await Escrow.methods.pay(escrowId).send({from: accounts[1]});
|
await Escrow.methods.pay(escrowId).send({from: accounts[1]});
|
||||||
await Escrow.methods.openCase(escrowId, 'Motive').send({from: accounts[1]});
|
await Escrow.methods.openCase(escrowId, 'Motive').send({from: accounts[1]});
|
||||||
|
|
||||||
receipt = await Escrow.methods.setArbitrationResult(escrowId, ARBITRATION_SOLVED_BUYER).send({from: arbitrator});
|
receipt = await Escrow.methods.setArbitrationResult(escrowId, ARBITRATION_SOLVED_BUYER).send({from: arbitrator});
|
||||||
const released = receipt.events.Released;
|
const released = receipt.events.Released;
|
||||||
assert(!!released, "Released() not triggered");
|
assert(!!released, "Released() not triggered");
|
||||||
|
|
||||||
|
const arbitratorBalanceAfter = await web3.eth.getBalance(arbitrator);
|
||||||
|
assert.strictEqual((toBN(arbitratorBalanceAfter).add(toBN(receipt.gasUsed))).toString(), (toBN(arbitratorBalanceBefore).add(toBN(feeAmount))).toString(), 'Arbitrator balance should have the fee');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should cancel escrow if case is solved in favor of the seller", async() => {
|
it("should cancel escrow if case is solved in favor of the seller", async() => {
|
||||||
|
@ -799,22 +803,6 @@ contract("Escrow", function() {
|
||||||
assert.strictEqual(parseInt(ethFeeBalance, 10), parseInt(ethFeeBalanceBefore, 10) + feeAmount, "Fee balance did not increase");
|
assert.strictEqual(parseInt(ethFeeBalance, 10), parseInt(ethFeeBalanceBefore, 10) + feeAmount, "Fee balance did not increase");
|
||||||
assert.strictEqual(parseInt(totalEthAfter, 10), parseInt(totalEthBefore, 10) + feeAmount + tradeAmount, "Total balance did not increase");
|
assert.strictEqual(parseInt(totalEthAfter, 10), parseInt(totalEthBefore, 10) + feeAmount + tradeAmount, "Total balance did not increase");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("fees can be withdrawn to burn address", async() => {
|
|
||||||
const ethFeeBalanceBefore = await Escrow.methods.feeTokenBalances(TestUtils.zeroAddress).call();
|
|
||||||
const totalEthBefore = await web3.eth.getBalance(Escrow.options.address);
|
|
||||||
const destAddressBalanceBefore = await web3.eth.getBalance(await Escrow.methods.feeDestination().call());
|
|
||||||
|
|
||||||
receipt = await Escrow.methods.withdrawFees(TestUtils.zeroAddress).send({from: accounts[0]});
|
|
||||||
|
|
||||||
const ethFeeBalanceAfter = await Escrow.methods.feeTokenBalances(TestUtils.zeroAddress).call();
|
|
||||||
const totalEthAfter = await web3.eth.getBalance(Escrow.options.address);
|
|
||||||
const destAddressBalanceAfter = await web3.eth.getBalance(await Escrow.methods.feeDestination().call());
|
|
||||||
|
|
||||||
assert.strictEqual(toBN(totalEthAfter).toString(), (toBN(totalEthBefore).sub(toBN(ethFeeBalanceBefore)).toString()), "Invalid contract balance");
|
|
||||||
assert.strictEqual(parseInt(ethFeeBalanceAfter, 10), 0, "Invalid fee balance");
|
|
||||||
assert.strictEqual(toBN(destAddressBalanceAfter).toString(), (toBN(destAddressBalanceBefore).add(toBN(ethFeeBalanceBefore)).toString()), "Invalid address balance");
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Other operations", async () => {
|
describe("Other operations", async () => {
|
||||||
|
|
Loading…
Reference in New Issue