Skip to content

Commit

Permalink
feat(eas): implement event attestation contract
Browse files Browse the repository at this point in the history
  • Loading branch information
thongxuan committed Apr 3, 2024
1 parent f804b6b commit 1a59634
Show file tree
Hide file tree
Showing 3 changed files with 492 additions and 1 deletion.
196 changes: 196 additions & 0 deletions contracts/payment/eas/LemonadeEventAttestation.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.19;

import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol";
import "@ethereum-attestation-service/eas-contracts/contracts/resolver/SchemaResolver.sol";
import "@ethereum-attestation-service/eas-contracts/contracts/resolver/examples/AttesterResolver.sol";

struct EventData {
string title;
string description;
uint256 start;
uint256 end;
string location;
uint256 guestLimit;
bytes32 externalEventId;
}

contract EventHostSchemaResolver is SchemaResolver {
bool internal onlyCreator;
LemonadeEventAttestation internal lea;

constructor(
IEAS _eas,
LemonadeEventAttestation _lea,
bool _onlyCreator
) SchemaResolver(_eas) {
onlyCreator = _onlyCreator;
lea = _lea;
}

function onAttest(
Attestation calldata _attestation,
uint256
) internal view override returns (bool) {
address attester = _attestation.attester;
bytes32 eventUID = abi.decode(_attestation.data, (bytes32));

bool isCreator = lea.isEventCreator(eventUID, attester);

//-- if is creator then
if (isCreator) return true;

//-- is not creator but onlyCreator is required
if (onlyCreator) return false;

bytes32 proofUID = _attestation.refUID;
Attestation memory hostAttestation = _eas.getAttestation(proofUID);

if (
hostAttestation.schema == lea.eventCohostSchemaId() &&
hostAttestation.recipient == attester
) {
bytes32 uid = abi.decode(hostAttestation.data, (bytes32));
return uid == eventUID;
}

return false;
}

function onRevoke(
Attestation calldata,
uint256
) internal pure override returns (bool) {
return true;
}
}

contract LemonadeEventAttestation is OwnableUpgradeable {
IEAS public eas;

bytes32 public eventSchemaId;
bytes32 public eventCohostSchemaId;
bytes32 public ticketTypeSchemaId;
bytes32 public ticketSchemaId;

mapping(bytes32 => address) internal eventCreators;

ISchemaResolver internal lemonadeAttesterSchemaResolver;
ISchemaResolver internal eventCreatorSchemaResolver;
ISchemaResolver internal eventHostsSchemaResolver;

event EventCreated(address host, bytes32 eventUID);

function initialize(address _eas) public initializer {
__Ownable_init();

eas = IEAS(_eas);

_initSchemas();
}

function registerEvent(EventData calldata eventData) external payable {
address creator = _msgSender();

AttestationRequestData memory data = AttestationRequestData(
creator,
0,
true,
"",
abi.encode(
eventData.title,
eventData.description,
eventData.start,
eventData.end,
eventData.location,
eventData.guestLimit,
eventData.externalEventId
),
msg.value
);

AttestationRequest memory attestation = AttestationRequest(
eventSchemaId,
data
);

bytes32 uid = eas.attest(attestation);

eventCreators[uid] = creator;

emit EventCreated(creator, uid);
}

function isEventCreator(
bytes32 _eventUID,
address _user
) public view returns (bool) {
return eventCreators[_eventUID] == _user;
}

function _initSchemas() internal onlyInitializing {
lemonadeAttesterSchemaResolver = new AttesterResolver(
eas,
address(this)
);
eventCreatorSchemaResolver = new EventHostSchemaResolver(
eas,
this,
true
);
eventHostsSchemaResolver = new EventHostSchemaResolver(
eas,
this,
false
);

_initEventSchema();
_initEventCohostSchema();
_initTicketTypeSchema();
_initTicketSchema();
}

function _initEventSchema() internal onlyInitializing {
string
memory schema = "string title, string description, uint256 start, uint256 end, string location, uint256 guestLimit, string externalEventId";

eventSchemaId = eas.getSchemaRegistry().register(
schema,
lemonadeAttesterSchemaResolver,
true
);
}

function _initEventCohostSchema() internal onlyInitializing {
string memory schema = "bytes32 eventUID";

eventCohostSchemaId = eas.getSchemaRegistry().register(
schema,
eventCreatorSchemaResolver,
true
);
}

function _initTicketTypeSchema() internal onlyInitializing {
string
memory schema = "bytes32 eventUID, string title, address currency, uint256 cost";

ticketTypeSchemaId = eas.getSchemaRegistry().register(
schema,
eventHostsSchemaResolver,
true
);
}

function _initTicketSchema() internal onlyInitializing {
string memory schema = "bytes32 eventUID, bytes32 ticketTypeUID";

ticketSchemaId = eas.getSchemaRegistry().register(
schema,
eventHostsSchemaResolver,
true
);
}
}
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,8 @@
"hardhat-deploy": "^0.11.34",
"ts-node": "^10.9.1",
"typescript": "^5.1.6"
},
"dependencies": {
"@ethereum-attestation-service/eas-sdk": "^1.5.0"
}
}
Loading

0 comments on commit 1a59634

Please sign in to comment.