Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/core/contracts/Escrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,11 @@ contract Escrow is IEscrow, ReentrancyGuard {
*/
function complete() external override notExpired adminOrReputationOracle {
require(
status == EscrowStatuses.Paid || status == EscrowStatuses.Partial,
status == EscrowStatuses.Paid ||
status == EscrowStatuses.Partial ||
(status == EscrowStatuses.Pending &&
bytes(intermediateResultsUrl).length > 0 &&
reservedFunds == 0),
'Invalid status'
);
_finalize();
Expand Down
51 changes: 50 additions & 1 deletion packages/core/test/Escrow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1394,7 +1394,7 @@ describe('Escrow', function () {
await setupEscrow();
});
describe('reverts', function () {
it('reverts when status is not Paid or Partial', async function () {
it('reverts when status is not Paid or Partial or intermediate results does not exist', async function () {
await expect(
escrow.connect(reputationOracle).complete()
).to.be.revertedWith('Invalid status');
Expand All @@ -1413,6 +1413,13 @@ describe('Escrow', function () {
escrow.connect(recordingOracle).complete()
).to.be.revertedWith('Unauthorised');
});

it('reverts when intermediate results exist but reserved funds is not 0', async function () {
storeResults();
await expect(
escrow.connect(reputationOracle).complete()
).to.be.revertedWith('Invalid status');
});
});

describe('succeeds', function () {
Expand Down Expand Up @@ -1472,6 +1479,48 @@ describe('Escrow', function () {
initialEscrowBalance - amounts[0]
);
});

it('Reputation oracle: completes the escrow successfully without payouts', async function () {
const initialLauncherBalance = await token.balanceOf(launcherAddress);
const initialEscrowBalance = await token.balanceOf(escrow.getAddress());

await storeResults(FIXTURE_URL, FIXTURE_HASH, 0n);

await expect(escrow.connect(reputationOracle).complete()).to.emit(
escrow,
'Completed'
);

expect(await escrow.status()).to.equal(Status.Complete);
expect(await escrow.remainingFunds()).to.equal('0');

const finalLauncherBalance = await token.balanceOf(launcherAddress);

expect(finalLauncherBalance - initialLauncherBalance).to.equal(
initialEscrowBalance
);
});

it('Admin: completes the escrow successfully without payouts', async function () {
const initialLauncherBalance = await token.balanceOf(launcherAddress);
const initialEscrowBalance = await token.balanceOf(escrow.getAddress());

await storeResults(FIXTURE_URL, FIXTURE_HASH, 0n);

await expect(escrow.connect(admin).complete()).to.emit(
escrow,
'Completed'
);

expect(await escrow.status()).to.equal(Status.Complete);
expect(await escrow.remainingFunds()).to.equal('0');

const finalLauncherBalance = await token.balanceOf(launcherAddress);

expect(finalLauncherBalance - initialLauncherBalance).to.equal(
initialEscrowBalance
);
});
});

describe('cancel()', () => {
Expand Down
Loading