Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Put Adapter Calls In Fetcher #1454

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions packages/smart/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export type MarketFactoryContractName =
| "CryptoCurrencyMarketFactoryV3"
| "TrustedMarketFactoryV3";
export type FetcherContractName =
| "NBAFetcher"
| "SportsFetcher"
| "MMAFetcher"
| "NFLFetcher"
| "MLBFetcher"
Expand Down Expand Up @@ -87,7 +87,7 @@ export const marketFactoryTypeToFetcherName: {
MMA: "MMAFetcher",
NFL: "NFLFetcher",
MLB: "MLBFetcher",
NBA: "NBAFetcher",
NBA: "SportsFetcher",
Crypto: "CryptoFetcher",
Grouped: "GroupedFetcher",
CryptoCurrency: "CryptoCurrencyFetcher",
Expand Down
50 changes: 0 additions & 50 deletions packages/smart/contracts/libraries/Sport.sol
Original file line number Diff line number Diff line change
Expand Up @@ -132,53 +132,3 @@ abstract contract Sport is AbstractMarketFactoryV3, LineHelper {
return getSportsEvent(_eventId).estimatedStartTime;
}
}

// TODO change this to work with the Fetcher contracts and use it there, since it's offchain-read-only.
abstract contract SportView is Sport {
// Only usable off-chain. Gas cost can easily eclipse block limit.
// Lists all events that could be resolved with a call to resolveEvent.
// Not all will be resolvable because this does not ensure the game ended.
function listResolvableEvents() external view returns (uint256[] memory) {
uint256 _totalResolvable = countResolvableEvents();
uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);

uint256 n = 0;
for (uint256 i = 0; i < listOfSportsEvents.length; i++) {
if (n > _totalResolvable) break;
uint256 _eventId = listOfSportsEvents[i];
if (isEventResolvable(_eventId)) {
_resolvableEvents[n] = _eventId;
n++;
}
}

return _resolvableEvents;
}

function countResolvableEvents() internal view returns (uint256) {
uint256 _totalResolvable = 0;
for (uint256 i = 0; i < listOfSportsEvents.length; i++) {
uint256 _eventId = listOfSportsEvents[i];
if (isEventResolvable(_eventId)) {
_totalResolvable++;
}
}
return _totalResolvable;
}

// Returns true if a call to resolveEvent is potentially useful.
function isEventResolvable(uint256 _eventId) internal view returns (bool) {
uint256[] memory _markets = getEventMarkets(_eventId);

bool _unresolved = false; // default because non-existing markets aren't resolvable
for (uint256 i = 0; i < _markets.length; i++) {
uint256 _marketId = _markets[i];
if (_marketId != 0 && !isMarketResolved(_marketId)) {
_unresolved = true;
break;
}
}

return _unresolved;
}
}
247 changes: 0 additions & 247 deletions packages/smart/contracts/turbo/Fetcher.sol
Original file line number Diff line number Diff line change
Expand Up @@ -147,253 +147,6 @@ abstract contract Fetcher {
}
}

abstract contract SportsFetcher is Fetcher {
struct SpecificMarketFactoryBundle {
MarketFactoryBundle super;
}

struct StaticEventBundle {
uint256 id;
StaticMarketBundle[] markets;
int256[] lines;
uint256 estimatedStartTime;
uint256 homeTeamId;
uint256 awayTeamId;
string homeTeamName;
string awayTeamName;
// Dynamics
Sport.SportsEventStatus status;
uint256 homeScore;
uint256 awayScore;
}

struct DynamicEventBundle {
uint256 id;
Sport.SportsEventStatus status;
DynamicMarketBundle[] markets;
uint256 homeScore;
uint256 awayScore;
}

function buildSpecificMarketFactoryBundle(address _marketFactory)
internal
view
returns (SpecificMarketFactoryBundle memory _bundle)
{
_bundle.super = buildMarketFactoryBundle(AbstractMarketFactoryV3(_marketFactory));
}

function fetchInitial(
address _marketFactory,
AMMFactory _ammFactory,
MasterChef _masterChef,
uint256 _offset,
uint256 _total
)
public
view
returns (
SpecificMarketFactoryBundle memory _marketFactoryBundle,
StaticEventBundle[] memory _eventBundles,
uint256 _lowestEventIndex,
uint256 _timestamp
)
{
_marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);
(_eventBundles, _lowestEventIndex) = buildStaticEventBundles(
_marketFactory,
_ammFactory,
_masterChef,
_offset,
_total
);
_timestamp = block.timestamp;
}

function fetchDynamic(
address _marketFactory,
AMMFactory _ammFactory,
uint256 _offset,
uint256 _total
)
public
view
returns (
DynamicEventBundle[] memory _bundles,
uint256 _lowestEventIndex,
uint256 _timestamp
)
{
(_bundles, _lowestEventIndex) = buildDynamicEventBundles(_marketFactory, _ammFactory, _offset, _total);
_timestamp = block.timestamp;
}

function buildStaticEventBundles(
address _marketFactory,
AMMFactory _ammFactory,
MasterChef _masterChef,
uint256 _offset,
uint256 _total
) internal view returns (StaticEventBundle[] memory _bundles, uint256 _lowestEventIndex) {
uint256[] memory _eventIds;
(_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);

_total = _eventIds.length;
_bundles = new StaticEventBundle[](_total);
for (uint256 i; i < _total; i++) {
_bundles[i] = buildStaticEventBundle(_marketFactory, _ammFactory, _masterChef, _eventIds[i]);
}
}

function buildDynamicEventBundles(
address _marketFactory,
AMMFactory _ammFactory,
uint256 _offset,
uint256 _total
) internal view returns (DynamicEventBundle[] memory _bundles, uint256 _lowestEventIndex) {
uint256[] memory _eventIds;
(_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);

_total = _eventIds.length;
_bundles = new DynamicEventBundle[](_total);
for (uint256 i; i < _total; i++) {
_bundles[i] = buildDynamicEventBundle(_marketFactory, _ammFactory, _eventIds[i]);
}
}

function buildStaticEventBundle(
address _marketFactory,
AMMFactory _ammFactory,
MasterChef _masterChef,
uint256 _eventId
) internal view returns (StaticEventBundle memory _bundle) {
Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);

StaticMarketBundle[] memory _markets = new StaticMarketBundle[](_event.markets.length);
for (uint256 i = 0; i < _markets.length; i++) {
_markets[i] = buildStaticMarketBundle(
AbstractMarketFactoryV3(_marketFactory),
_ammFactory,
_masterChef,
_event.markets[i]
);
}

_bundle.id = _eventId;
_bundle.status = _event.status;
_bundle.markets = _markets;
_bundle.lines = _event.lines;
_bundle.estimatedStartTime = _event.estimatedStartTime;
_bundle.homeTeamId = _event.homeTeamId;
_bundle.awayTeamId = _event.awayTeamId;
_bundle.homeTeamName = _event.homeTeamName;
_bundle.awayTeamName = _event.awayTeamName;
_bundle.homeScore = _event.homeScore;
_bundle.awayScore = _event.awayScore;
}

function buildDynamicEventBundle(
address _marketFactory,
AMMFactory _ammFactory,
uint256 _eventId
) internal view returns (DynamicEventBundle memory _bundle) {
Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);

DynamicMarketBundle[] memory _markets = new DynamicMarketBundle[](_event.markets.length);
for (uint256 i = 0; i < _markets.length; i++) {
_markets[i] = buildDynamicMarketBundle(
AbstractMarketFactoryV3(_marketFactory),
_ammFactory,
_event.markets[i]
);
}

_bundle.id = _eventId;
_bundle.markets = _markets;
_bundle.status = _event.status;
_bundle.homeScore = _event.homeScore;
_bundle.awayScore = _event.awayScore;
}

// Starts from the end of the events list because newer events are more interesting.
// _offset is skipping all events, not just interesting events
function listOfInterestingEvents(
address _marketFactory,
uint256 _offset,
uint256 _total
) internal view returns (uint256[] memory _interestingEventIds, uint256 _eventIndex) {
_interestingEventIds = new uint256[](_total);

uint256 _eventCount = Sport(_marketFactory).eventCount();

// No events so return nothing. (needed to avoid integer underflow below)
if (_eventCount == 0) {
return (new uint256[](0), 0);
}

uint256 _max = _eventCount;

// No remaining events so return nothing. (needed to avoid integer underflow below)
if (_offset > _max) {
return (new uint256[](0), 0);
}

uint256 _collectedEvents = 0;
_eventIndex = _max - _offset;
while (true) {
if (_collectedEvents >= _total) break;
if (_eventIndex == 0) break;

_eventIndex--; // starts out one too high, so this works

(Sport.SportsEvent memory _event, uint256 _eventId) =
Sport(_marketFactory).getSportsEventByIndex(_eventIndex);

if (isEventInteresting(_event, AbstractMarketFactoryV3(_marketFactory))) {
_interestingEventIds[_collectedEvents] = _eventId;
_collectedEvents++;
}
}

if (_total > _collectedEvents) {
assembly {
// shortens array
mstore(_interestingEventIds, _collectedEvents)
}
}
}

function isEventInteresting(Sport.SportsEvent memory _event, AbstractMarketFactoryV3 _marketFactory)
private
view
returns (bool)
{
for (uint256 i = 0; i < _event.markets.length; i++) {
uint256 _marketId = _event.markets[i];
if (openOrHasWinningShares(_marketFactory, _marketId)) {
return true;
}
}
return false;
}
}

contract NBAFetcher is SportsFetcher {
constructor() Fetcher("NBA", "TBD") {}
}

contract MLBFetcher is SportsFetcher {
constructor() Fetcher("MLB", "TBD") {}
}

contract MMAFetcher is SportsFetcher {
constructor() Fetcher("MMA", "TBD") {}
}

contract NFLFetcher is SportsFetcher {
constructor() Fetcher("NFL", "TBD") {}
}

contract CryptoFetcher is Fetcher {
constructor() Fetcher("Crypto", "TBD") {}

Expand Down
2 changes: 1 addition & 1 deletion packages/smart/contracts/turbo/MLBMarketFactoryV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import "../libraries/HasHeadToHeadMarket.sol";
import "../libraries/ResolveByScore.sol";
import "../libraries/Versioned.sol";

contract MLBMarketFactoryV3 is AbstractMarketFactoryV3, SportView, HasHeadToHeadMarket, ResolvesByScore, Versioned {
contract MLBMarketFactoryV3 is AbstractMarketFactoryV3, Sport, HasHeadToHeadMarket, ResolvesByScore, Versioned {
using SafeMathUint256 for uint256;
using SafeMathInt256 for int256;

Expand Down
2 changes: 1 addition & 1 deletion packages/smart/contracts/turbo/MMAMarketFactoryV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import "../libraries/ResolveByFiat.sol";
import "../libraries/HasHeadToHeadMarket.sol";
import "../libraries/Versioned.sol";

contract MMAMarketFactoryV3 is AbstractMarketFactoryV3, SportView, ResolvesByFiat, HasHeadToHeadMarket, Versioned {
contract MMAMarketFactoryV3 is AbstractMarketFactoryV3, Sport, ResolvesByFiat, HasHeadToHeadMarket, Versioned {
using SafeMathUint256 for uint256;
using SafeMathInt256 for int256;

Expand Down
2 changes: 1 addition & 1 deletion packages/smart/contracts/turbo/NBAMarketFactoryV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import "../libraries/Versioned.sol";

contract NBAMarketFactoryV3 is
AbstractMarketFactoryV3,
SportView,
Sport,
HasHeadToHeadMarket,
HasSpreadMarket,
HasOverUnderMarket,
Expand Down
2 changes: 1 addition & 1 deletion packages/smart/contracts/turbo/NCAAFBMarketFactoryV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import "../libraries/Versioned.sol";
// and the invalid outcome is just No Contest.
contract NCAAFBMarketFactoryV3 is
AbstractMarketFactoryV3,
SportView,
Sport,
HasHeadToHeadMarket,
HasSpreadMarket,
HasOverUnderMarket,
Expand Down
2 changes: 1 addition & 1 deletion packages/smart/contracts/turbo/NFLMarketFactoryV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import "../libraries/Versioned.sol";
// As a consequence, half points are not added to the lines.
contract NFLMarketFactoryV3 is
AbstractMarketFactoryV3,
SportView,
Sport,
HasHeadToHeadMarket,
HasSpreadMarket,
HasOverUnderMarket,
Expand Down
Loading