Skip to content

Commit

Permalink
Add dust limit check in buy and before creating a new offer
Browse files Browse the repository at this point in the history
  • Loading branch information
gbalabasquer committed Jan 30, 2019
1 parent cc5f6b9 commit 0281455
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 3 deletions.
20 changes: 18 additions & 2 deletions src/matching_market.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,22 @@ contract MatchingMarket is MatchingEvents, ExpiringMarket, DSNote {
mapping(address => uint) public _dust; //minimum sell amount for a token to avoid dust offers
mapping(uint => uint) public _near; //next unsorted offer id
uint _head; //first unsorted offer id
uint public dustId; // id of the latest offer marked as dust


function MatchingMarket(uint64 close_time) ExpiringMarket(close_time) public {
}

// After close, anyone can cancel an offer
modifier can_cancel(uint id) {
require(isActive(id), "Offer was deleted or taken, or never existed.");
require(
isClosed() || msg.sender == getOwner(id) || id == dustId,
"Offer can not be cancelled because user is not owner, and market is open, and offer sells required amount of tokens."
);
_;
}

// ---- Public entrypoints ---- //

function make(
Expand Down Expand Up @@ -388,6 +400,11 @@ contract MatchingMarket is MatchingEvents, ExpiringMarket, DSNote {
_unsort(id);
}
require(super.buy(id, amount));
// If offer has become dust during buy, we cancel it
if (isActive(id) && offers[id].pay_amt < _dust[offers[id].pay_gem]) {
dustId = id; //enable current msg.sender to call cancel(id)
cancel(id);
}
return true;
}

Expand Down Expand Up @@ -504,7 +521,6 @@ contract MatchingMarket is MatchingEvents, ExpiringMarket, DSNote {
}
// ^ The `rounding` parameter is a compromise borne of a couple days
// of discussion.

buy(best_maker_id, min(m_pay_amt, t_buy_amt));
t_buy_amt_old = t_buy_amt;
t_buy_amt = sub(t_buy_amt, min(m_pay_amt, t_buy_amt));
Expand All @@ -515,7 +531,7 @@ contract MatchingMarket is MatchingEvents, ExpiringMarket, DSNote {
}
}

if (t_buy_amt > 0 && t_pay_amt > 0) {
if (t_buy_amt > 0 && t_pay_amt > 0 && t_pay_amt >= _dust[t_pay_gem]) {
//new offer should be created
id = super.offer(t_pay_amt, t_pay_gem, t_buy_amt, t_buy_gem);
//insert offer into the sorted list
Expand Down
32 changes: 31 additions & 1 deletion src/matching_market.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,37 @@ contract OrderMatchingTest is DSTest, EventfulMarket, MatchingEvents {
assertEq(otc.getMinSell(mkr), 30);
offer_id[1] = otc.offer(30, mkr, 90, dai, 0);
}

function testDustMakerOfferCanceled() public {
assert(otc.matchingEnabled());
dai.transfer(user1, 30);
user1.doApprove(otc, 30, dai);
mkr.approve(otc, 25);
otc.setMinSell(dai, 10);
uint id0 = user1.doOffer(30, dai, 30, mkr, 0);
uint id1 = otc.offer(25, mkr, 25, dai, 0);
assert(!otc.isActive(id0));
assert(!otc.isActive(id1));
}
function testDustNotNewDustOfferIsCreated() public {
assert(otc.matchingEnabled());
dai.transfer(user1, 30);
user1.doApprove(otc, 30, dai);
mkr.approve(otc, 25);
otc.setMinSell(dai, 10);
uint id0 = otc.offer(25, mkr, 25, dai, 0);
uint id1 = user1.doOffer(30, dai, 30, mkr, 0);
assert(!otc.isActive(id0));
assert(!otc.isActive(id1));
}
function testBuyDustOfferCanceled() public {
dai.transfer(user1, 30);
user1.doApprove(otc, 30, dai);
mkr.approve(otc, 25);
otc.setMinSell(dai, 10);
uint id0 = user1.doOffer(30, dai, 30, mkr, 0);
otc.buy(id0, 25);
assert(!otc.isActive(id0));
}
function testErroneousUserHigherIdStillWorks() public {
dai.transfer(user1, 10);
user1.doApprove(otc, 10, dai);
Expand Down

0 comments on commit 0281455

Please sign in to comment.