Skip to content
This repository has been archived by the owner on May 5, 2023. It is now read-only.

Commit

Permalink
Provide average price for market offers
Browse files Browse the repository at this point in the history
  • Loading branch information
amarinkovic committed Feb 4, 2022
1 parent d9a7b5a commit f0242a1
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 19 deletions.
4 changes: 2 additions & 2 deletions contracts/EntityTokensFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ contract EntityTokensFacet is EternalStorage, Controller, EntityFacetBase, IEnti
// if we created this offer
if (entity == address(this)) {
// check entity token matches sell token
(, address sellToken, , , address buyToken, , , , , ,) = _getMarket().getOffer(_offerId);
(, address sellToken, , , address buyToken, , , , , , ,) = _getMarket().getOffer(_offerId);
address tokenAddress = dataAddress["token"];
require(tokenAddress == sellToken, "sell token must be entity token");

Expand Down Expand Up @@ -198,7 +198,7 @@ contract EntityTokensFacet is EternalStorage, Controller, EntityFacetBase, IEnti
// if we created this offer
if (entity == address(this)) {
// check entity token matches sell token
(, address sellToken, , , , , , , , ,) = _getMarket().getOffer(_offerId);
(, address sellToken, , , , , , , , , ,) = _getMarket().getOffer(_offerId);
address tokenAddress = dataAddress["token"];
require(tokenAddress == sellToken, "sell token must be entity token");

Expand Down
37 changes: 22 additions & 15 deletions contracts/MarketCoreFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ contract MarketCoreFacet is EternalStorage, Controller, MarketFacetBase, IDiamon
uint256 remainingBuyAmount_;
uint256 remainingSellAmount_;

(remainingBuyAmount_, remainingSellAmount_) = _matchToExistingOffers(
(remainingBuyAmount_, remainingSellAmount_, ) = _matchToExistingOffers(
_sellToken,
_sellAmount,
_buyToken,
Expand Down Expand Up @@ -149,8 +149,9 @@ contract MarketCoreFacet is EternalStorage, Controller, MarketFacetBase, IDiamon

uint256 remainingBuyAmount_;
uint256 remainingSellAmount_;
uint256 matchedAmount_;

(remainingBuyAmount_, remainingSellAmount_) = _matchToExistingOffers(
(remainingBuyAmount_, remainingSellAmount_, matchedAmount_) = _matchToExistingOffers(
_sellToken,
_sellAmount,
_buyToken,
Expand All @@ -162,17 +163,20 @@ contract MarketCoreFacet is EternalStorage, Controller, MarketFacetBase, IDiamon

require(remainingSellAmount_ == 0, "not enough orders in market");

// market offer settled, create offer for history
// market offer settled, create record for history
uint256 marketOfferId = _createOffer(
_sellToken,
_sellAmount,
_buyToken,
0,
matchedAmount_,
FEE_SCHEDULE_STANDARD,
msg.sender,
"",
true
);
// `_sellAmount` is used above for setting the initial sell amount on the offer,
// then it's updated to the actual remaining sell amount after offer execution
dataUint256[__i(marketOfferId, "sellAmount")] = remainingSellAmount_;
}

// Private
Expand Down Expand Up @@ -281,18 +285,22 @@ contract MarketCoreFacet is EternalStorage, Controller, MarketFacetBase, IDiamon
bool marketOffer
)
private
returns (uint256 remainingBuyAmount_, uint256 remainingSellAmount_)
returns (uint256 remainingBuyAmount_, uint256 remainingSellAmount_, uint256 matchedAmount_)
{
remainingBuyAmount_ = _buyAmount;
remainingSellAmount_ = _sellAmount;

// there is at least one offer stored for token pair
uint256 bestOfferId = dataUint256[__iaa(0, _buyToken, _sellToken, "bestOfferId")];
if(marketOffer == true) {
require(bestOfferId != 0, "not enough orders in market");
}

while (bestOfferId > 0) {
matchedAmount_ = 0;

while (remainingSellAmount_ != 0 && (remainingBuyAmount_ != 0 || marketOffer)) {

// there is at least one offer stored for token pair
uint256 bestOfferId = dataUint256[__iaa(0, _buyToken, _sellToken, "bestOfferId")];
if(marketOffer == true) {
require(bestOfferId != 0, "not enough orders in market");
} else if(bestOfferId == 0) {
break;
}

uint256 bestBuyAmount = dataUint256[__i(bestOfferId, "buyAmount")];
uint256 bestSellAmount = dataUint256[__i(bestOfferId, "sellAmount")];

Expand Down Expand Up @@ -323,6 +331,7 @@ contract MarketCoreFacet is EternalStorage, Controller, MarketFacetBase, IDiamon
{
// do the buy
uint256 finalSellAmount = bestBuyAmount < remainingSellAmount_ ? bestBuyAmount : remainingSellAmount_;
matchedAmount_ += finalSellAmount;

_buyWithObserver(
bestOfferId,
Expand All @@ -341,8 +350,6 @@ contract MarketCoreFacet is EternalStorage, Controller, MarketFacetBase, IDiamon
if (remainingSellAmount_ == 0 || (remainingBuyAmount_ == 0 && !marketOffer)) {
break;
}

bestOfferId = dataUint256[__iaa(0, _buyToken, _sellToken, "bestOfferId")];
}
}

Expand Down
3 changes: 3 additions & 0 deletions contracts/MarketDataFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ contract MarketDataFacet is EternalStorage, Controller, MarketFacetBase, IDiamon
address buyToken_,
uint256 buyAmount_,
uint256 buyAmountInitial_,
uint256 averagePrice_,
uint256 feeSchedule_,
address notify_,
bytes memory notifyData_,
Expand All @@ -69,6 +70,8 @@ contract MarketDataFacet is EternalStorage, Controller, MarketFacetBase, IDiamon
buyToken_ = dataAddress[__i(_offerId, "buyToken")];
buyAmount_ = dataUint256[__i(_offerId, "buyAmount")];
buyAmountInitial_ = dataUint256[__i(_offerId, "buyAmountInitial")];
uint256 soldAmount = sellAmountInitial_ - sellAmount_;
averagePrice_ = soldAmount > 0 ? buyAmount_.div(soldAmount) : 0;
feeSchedule_ = dataUint256[__i(_offerId, "feeSchedule")];
notify_ = dataAddress[__i(_offerId, "notify")];
notifyData_ = dataBytes[__i(_offerId, "notifyData")];
Expand Down
4 changes: 2 additions & 2 deletions contracts/PolicyTrancheTokensFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ contract PolicyTrancheTokensFacet is EternalStorage, Controller, IDiamondFacet,
// if we are in the initial sale period
if (dataUint256[__i(trancheId, "state")] == TRANCHE_STATE_SELLING) {
// check tranche token matches sell token
(, address sellToken, , , , , , , , ,) = _getMarket().getOffer(_offerId);
(, address sellToken, , , , , , , , , ,) = _getMarket().getOffer(_offerId);
address trancheAddress = dataAddress[__i(trancheId, "address")];
require(trancheAddress == sellToken, "sell token must be tranche token");
// record how many "shares" were sold
Expand Down Expand Up @@ -174,7 +174,7 @@ contract PolicyTrancheTokensFacet is EternalStorage, Controller, IDiamondFacet,
// if we are in the policy buyback state
if (dataUint256["state"] == POLICY_STATE_BUYBACK) {
// check tranche token matches buy token
(, , , , address buyToken, , , , , ,) = _getMarket().getOffer(_offerId);
(, , , , address buyToken, , , , , , ,) = _getMarket().getOffer(_offerId);
address trancheAddress = dataAddress[__i(trancheId, "address")];
require(trancheAddress == buyToken, "buy token must be tranche token");

Expand Down
2 changes: 2 additions & 0 deletions contracts/base/IMarketDataFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ interface IMarketDataFacet {
* @return buyToken_ buy token.
* @return buyAmount_ buy amount.
* @return buyAmountInitial_ initial buy amount.
* @return averagePrice_ average price paid.
* @return feeSchedule_ fee schedule.
* @return notify_ Contract to notify when a trade takes place and/or order gets cancelled.
* @return notifyData_ Data to pass through to the notified contract.
Expand All @@ -112,6 +113,7 @@ interface IMarketDataFacet {
address buyToken_,
uint256 buyAmount_,
uint256 buyAmountInitial_,
uint256 averagePrice_,
uint256 feeSchedule_,
address notify_,
bytes memory notifyData_,
Expand Down
15 changes: 15 additions & 0 deletions test/market.js
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,21 @@ describe('Market', () => {
await erc20DAI.balanceOf(accounts[3]).should.eventually.eq(toWei('970').toString())
await erc20WETH.balanceOf(accounts[3]).should.eventually.eq(toWei('1020').toString())
})

it('should create a fulfilled market offer after successfully executing', async () => {
const lastOfferId = await market.getLastOfferId()

await erc20WETH.approve( market.address, toBN(10e18), { from: accounts[1] } )
await market.executeMarketOffer(erc20WETH.address, toBN(10e18), erc20DAI.address, { from: accounts[1] })

const marketOfferId = await market.getLastOfferId()
const marketOffer = await market.getOffer(marketOfferId)

expect(marketOffer.state_).to.eq(OFFER_STATE_FULFILLED)
expect(marketOffer.sellAmount_.toString()).to.eq('0')
expect(marketOffer.averagePrice_.toString()).to.eq('1')

})
})

describe('can match a pair of matching offers', () => {
Expand Down

0 comments on commit f0242a1

Please sign in to comment.