-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create the first version of Billboard contracts.
- Loading branch information
Showing
7 changed files
with
1,117 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,113 +1,113 @@ | ||
CurationTest:testCannotCurateERC20CurateZeroAmount() (gas: 12244) | ||
CurationTest:testCannotCurateERC20EmptyURI() (gas: 15838) | ||
CurationTest:testCannotCurateERC20IfNotApproval() (gas: 21671) | ||
CurationTest:testCannotCurateERC20SelfCuration() (gas: 16082) | ||
CurationTest:testCannotCurateERC20ZeroAddress() (gas: 15950) | ||
CurationTest:testCannotCurateNativeTokenCurateZeroAmount() (gas: 10008) | ||
CurationTest:testCannotCurateNativeTokenEmptyURI() (gas: 16508) | ||
CurationTest:testCannotCurateNativeTokenSelfCuration() (gas: 16763) | ||
CurationTest:testCannotCurateNativeTokenToContractRejector() (gas: 28604) | ||
CurationTest:testCannotCurateNativeTokenZeroAddress() (gas: 16528) | ||
CurationTest:testERC20Curation() (gas: 59976) | ||
CurationTest:testNativeTokenCuration() (gas: 60127) | ||
CurationTest:testNativeTokenCurationToContractAcceptor() (gas: 37508) | ||
LogbookTest:testClaim() (gas: 134763) | ||
LogbookTest:testDonate(uint96) (runs: 256, μ: 155493, ~: 156942) | ||
LogbookTest:testDonateWithCommission(uint96,uint96) (runs: 256, μ: 152152, ~: 140464) | ||
LogbookTest:testFork(uint96,string) (runs: 256, μ: 446796, ~: 451347) | ||
LogbookTest:testForkRecursively(uint8,uint96) (runs: 256, μ: 4224034, ~: 1016125) | ||
LogbookTest:testForkWithCommission(uint96,string,uint256) (runs: 256, μ: 542623, ~: 257710) | ||
LogbookTest:testMulticall() (gas: 285685) | ||
LogbookTest:testPublicSale() (gas: 202868) | ||
LogbookTest:testPublish(string) (runs: 256, μ: 264518, ~: 264648) | ||
LogbookTest:testPublishEn1000() (gas: 243576) | ||
LogbookTest:testPublishEn140() (gas: 221340) | ||
LogbookTest:testPublishEn200() (gas: 222925) | ||
LogbookTest:testPublishEn2000() (gas: 270119) | ||
LogbookTest:testPublishEn300() (gas: 225383) | ||
LogbookTest:testPublishEn50() (gas: 218821) | ||
LogbookTest:testPublishEn500() (gas: 230367) | ||
LogbookTest:testPublishEn5000() (gas: 348595) | ||
LogbookTest:testPublishZh100() (gas: 224601) | ||
LogbookTest:testPublishZh20() (gas: 218803) | ||
LogbookTest:testPublishZh200() (gas: 231171) | ||
LogbookTest:testPublishZh2000() (gas: 371254) | ||
LogbookTest:testPublishZh50() (gas: 221251) | ||
LogbookTest:testPublishZh500() (gas: 251055) | ||
LogbookTest:testPublishZh5000() (gas: 607789) | ||
LogbookTest:testSetDescription() (gas: 140859) | ||
LogbookTest:testSetForkPrice() (gas: 153948) | ||
LogbookTest:testSetTitle() (gas: 168804) | ||
LogbookTest:testSplitRoyalty(uint8,uint8,uint96) (runs: 256, μ: 2065544, ~: 637605) | ||
LogbookTest:testWithdraw() (gas: 7296693) | ||
LogbookNFTSVGTest:testTokenURI(uint8,uint8,uint16) (runs: 256, μ: 2026391, ~: 1315240) | ||
SnapperTest:testCannotInitRegionByNotOwner() (gas: 11390) | ||
SnapperTest:testCannotReInitRegion() (gas: 14423) | ||
SnapperTest:testCannotTakeSnapshotBeforeInit() (gas: 15792) | ||
SnapperTest:testCannotTakeSnapshotByNotOwner() (gas: 12528) | ||
SnapperTest:testCannotTakeSnapshotWrongLastBlock() (gas: 49279) | ||
SnapperTest:testCannotTakeSnapshotWrongSnapshotBlock() (gas: 24049) | ||
SnapperTest:testInitRegion(uint256) (runs: 256, μ: 114604, ~: 114604) | ||
SnapperTest:testTakeSnapshot() (gas: 47962) | ||
ACLManagerTest:testCannotGrantACLManagerRole() (gas: 12231) | ||
ACLManagerTest:testCannotGrantRoleByNonACLManager() (gas: 17403) | ||
ACLManagerTest:testCannotGrantRoleToZeroAddress() (gas: 12220) | ||
ACLManagerTest:testCannotRenounceRoleByACLManager() (gas: 12081) | ||
ACLManagerTest:testCannotRenounceRoleByAttacker() (gas: 12371) | ||
ACLManagerTest:testCannotTransferRoleByAttacker() (gas: 12498) | ||
ACLManagerTest:testCannotTransferRoleToZeroAddress() (gas: 12218) | ||
ACLManagerTest:testGrantRole() (gas: 23547) | ||
ACLManagerTest:testRenounceRole() (gas: 27841) | ||
ACLManagerTest:testRoles() (gas: 15393) | ||
ACLManagerTest:testTransferRole() (gas: 21528) | ||
TheSpaceTest:testBatchBid() (gas: 690679) | ||
TheSpaceTest:testBatchSetPixels(uint16,uint8) (runs: 256, μ: 369115, ~: 370766) | ||
TheSpaceTest:testBidDefaultedToken() (gas: 409339) | ||
TheSpaceTest:testBidExistingToken() (gas: 354974) | ||
TheSpaceTest:testBidNewToken() (gas: 301167) | ||
TheSpaceTest:testCanTransferFromIfSettleTax() (gas: 355017) | ||
TheSpaceTest:testCannotBidExceedAllowance() (gas: 60907) | ||
TheSpaceTest:testCannotBidOutBoundTokens() (gas: 260493) | ||
TheSpaceTest:testCannotBidPriceTooLow() (gas: 341680) | ||
TheSpaceTest:testCannotGetTaxWithNonExistingToken() (gas: 16426) | ||
TheSpaceTest:testCannotGetTokenURIInLogicContract() (gas: 296920) | ||
TheSpaceTest:testCannotSetColorByAttacker() (gas: 302856) | ||
TheSpaceTest:testCannotSetConfigByAttacker() (gas: 12078) | ||
TheSpaceTest:testCannotSetPixel(uint256) (runs: 256, μ: 312359, ~: 312359) | ||
TheSpaceTest:testCannotSetPriceByNonOwner() (gas: 302932) | ||
TheSpaceTest:testCannotSetTokenImageURIByNonACLManager() (gas: 11887) | ||
TheSpaceTest:testCannotSetTotalSupplyByAttacker() (gas: 11883) | ||
TheSpaceTest:testCannotTransferFromIfDefault() (gas: 394091) | ||
TheSpaceTest:testCannotUpgradeByAttacker() (gas: 11564) | ||
TheSpaceTest:testCollectableTax() (gas: 333312) | ||
TheSpaceTest:testDefault() (gas: 390517) | ||
ACLManagerTest:testCannotGrantACLManagerRole() (gas: 188) | ||
ACLManagerTest:testCannotGrantRoleByNonACLManager() (gas: 165) | ||
ACLManagerTest:testCannotGrantRoleToZeroAddress() (gas: 142) | ||
ACLManagerTest:testCannotRenounceRoleByACLManager() (gas: 164) | ||
ACLManagerTest:testCannotRenounceRoleByAttacker() (gas: 165) | ||
ACLManagerTest:testCannotTransferRoleByAttacker() (gas: 143) | ||
ACLManagerTest:testCannotTransferRoleToZeroAddress() (gas: 166) | ||
ACLManagerTest:testGrantRole() (gas: 186) | ||
ACLManagerTest:testRenounceRole() (gas: 143) | ||
ACLManagerTest:testRoles() (gas: 15288) | ||
ACLManagerTest:testTransferRole() (gas: 187) | ||
CurationTest:testCannotCurateERC20CurateZeroAmount() (gas: 12194) | ||
CurationTest:testCannotCurateERC20EmptyURI() (gas: 15797) | ||
CurationTest:testCannotCurateERC20IfNotApproval() (gas: 21624) | ||
CurationTest:testCannotCurateERC20SelfCuration() (gas: 16031) | ||
CurationTest:testCannotCurateERC20ZeroAddress() (gas: 15899) | ||
CurationTest:testCannotCurateNativeTokenCurateZeroAmount() (gas: 9958) | ||
CurationTest:testCannotCurateNativeTokenEmptyURI() (gas: 16468) | ||
CurationTest:testCannotCurateNativeTokenSelfCuration() (gas: 16713) | ||
CurationTest:testCannotCurateNativeTokenToContractRejector() (gas: 28554) | ||
CurationTest:testCannotCurateNativeTokenZeroAddress() (gas: 16488) | ||
CurationTest:testERC20Curation() (gas: 59908) | ||
CurationTest:testNativeTokenCuration() (gas: 60085) | ||
CurationTest:testNativeTokenCurationToContractAcceptor() (gas: 37466) | ||
LogbookNFTSVGTest:testTokenURI(uint8,uint8,uint16) (runs: 256, μ: 2035888, ~: 1310779) | ||
LogbookTest:testClaim() (gas: 135608) | ||
LogbookTest:testDonate(uint96) (runs: 256, μ: 155485, ~: 156936) | ||
LogbookTest:testDonateWithCommission(uint96,uint96) (runs: 256, μ: 150646, ~: 140444) | ||
LogbookTest:testFork(uint96,string) (runs: 256, μ: 450748, ~: 453928) | ||
LogbookTest:testForkRecursively(uint8,uint96) (runs: 256, μ: 4403316, ~: 1014389) | ||
LogbookTest:testForkWithCommission(uint96,string,uint256) (runs: 256, μ: 497254, ~: 257636) | ||
LogbookTest:testMulticall() (gas: 284999) | ||
LogbookTest:testPublicSale() (gas: 204837) | ||
LogbookTest:testPublish(string) (runs: 256, μ: 264065, ~: 263590) | ||
LogbookTest:testPublishEn1000() (gas: 243477) | ||
LogbookTest:testPublishEn140() (gas: 221241) | ||
LogbookTest:testPublishEn200() (gas: 222826) | ||
LogbookTest:testPublishEn2000() (gas: 270020) | ||
LogbookTest:testPublishEn300() (gas: 225284) | ||
LogbookTest:testPublishEn50() (gas: 218722) | ||
LogbookTest:testPublishEn500() (gas: 230268) | ||
LogbookTest:testPublishEn5000() (gas: 348496) | ||
LogbookTest:testPublishZh100() (gas: 224502) | ||
LogbookTest:testPublishZh20() (gas: 218704) | ||
LogbookTest:testPublishZh200() (gas: 231104) | ||
LogbookTest:testPublishZh2000() (gas: 371155) | ||
LogbookTest:testPublishZh50() (gas: 221152) | ||
LogbookTest:testPublishZh500() (gas: 250956) | ||
LogbookTest:testPublishZh5000() (gas: 607690) | ||
LogbookTest:testSetDescription() (gas: 140760) | ||
LogbookTest:testSetForkPrice() (gas: 153925) | ||
LogbookTest:testSetTitle() (gas: 168680) | ||
LogbookTest:testSplitRoyalty(uint8,uint8,uint96) (runs: 256, μ: 1862299, ~: 636792) | ||
LogbookTest:testWithdraw() (gas: 7284400) | ||
SnapperTest:testCannotInitRegionByNotOwner() (gas: 11365) | ||
SnapperTest:testCannotReInitRegion() (gas: 14373) | ||
SnapperTest:testCannotTakeSnapshotBeforeInit() (gas: 15717) | ||
SnapperTest:testCannotTakeSnapshotByNotOwner() (gas: 12478) | ||
SnapperTest:testCannotTakeSnapshotWrongLastBlock() (gas: 49242) | ||
SnapperTest:testCannotTakeSnapshotWrongSnapshotBlock() (gas: 23899) | ||
SnapperTest:testInitRegion(uint256) (runs: 256, μ: 114408, ~: 114408) | ||
SnapperTest:testTakeSnapshot() (gas: 47831) | ||
TheSpaceTest:testBatchBid() (gas: 690308) | ||
TheSpaceTest:testBatchSetPixels(uint16,uint8) (runs: 256, μ: 368737, ~: 370338) | ||
TheSpaceTest:testBidDefaultedToken() (gas: 409416) | ||
TheSpaceTest:testBidExistingToken() (gas: 355023) | ||
TheSpaceTest:testBidNewToken() (gas: 301184) | ||
TheSpaceTest:testCanTransferFromIfSettleTax() (gas: 355069) | ||
TheSpaceTest:testCannotBidExceedAllowance() (gas: 60910) | ||
TheSpaceTest:testCannotBidOutBoundTokens() (gas: 260482) | ||
TheSpaceTest:testCannotBidPriceTooLow() (gas: 341674) | ||
TheSpaceTest:testCannotGetTaxWithNonExistingToken() (gas: 16401) | ||
TheSpaceTest:testCannotGetTokenURIInLogicContract() (gas: 298473) | ||
TheSpaceTest:testCannotSetColorByAttacker() (gas: 302848) | ||
TheSpaceTest:testCannotSetConfigByAttacker() (gas: 12053) | ||
TheSpaceTest:testCannotSetPixel(uint256) (runs: 256, μ: 312357, ~: 312357) | ||
TheSpaceTest:testCannotSetPriceByNonOwner() (gas: 302924) | ||
TheSpaceTest:testCannotSetTokenImageURIByNonACLManager() (gas: 11862) | ||
TheSpaceTest:testCannotSetTotalSupplyByAttacker() (gas: 11858) | ||
TheSpaceTest:testCannotTransferFromIfDefault() (gas: 394147) | ||
TheSpaceTest:testCannotUpgradeByAttacker() (gas: 11539) | ||
TheSpaceTest:testCollectableTax() (gas: 333364) | ||
TheSpaceTest:testDefault() (gas: 390575) | ||
TheSpaceTest:testGetConfig() (gas: 14302) | ||
TheSpaceTest:testGetExistingPixel() (gas: 309403) | ||
TheSpaceTest:testGetNonExistingPixel() (gas: 60251) | ||
TheSpaceTest:testGetNonExistingPrice() (gas: 19524) | ||
TheSpaceTest:testGetOwner() (gas: 346900) | ||
TheSpaceTest:testGetExistingPixel() (gas: 309428) | ||
TheSpaceTest:testGetNonExistingPixel() (gas: 60258) | ||
TheSpaceTest:testGetNonExistingPrice() (gas: 19529) | ||
TheSpaceTest:testGetOwner() (gas: 346931) | ||
TheSpaceTest:testGetOwnerOfNonExistingToken() (gas: 13346) | ||
TheSpaceTest:testGetPixelsByOwnerWithNoPixels() (gas: 24265) | ||
TheSpaceTest:testGetPixelsByOwnerWithOnePixel() (gas: 319489) | ||
TheSpaceTest:testGetPixelsPageByOwnerWithPixels() (gas: 586574) | ||
TheSpaceTest:testGetPrice() (gas: 297984) | ||
TheSpaceTest:testGetTax() (gas: 375340) | ||
TheSpaceTest:testGetTokenImageURI() (gas: 14407) | ||
TheSpaceTest:testGetTokenURI() (gas: 331148) | ||
TheSpaceTest:testSetColor() (gas: 328831) | ||
TheSpaceTest:testSetMintTax() (gas: 269213) | ||
TheSpaceTest:testSetPixel(uint256) (runs: 256, μ: 398774, ~: 398774) | ||
TheSpaceTest:testSetPrice(uint256) (runs: 256, μ: 302135, ~: 302135) | ||
TheSpaceTest:testSetPriceByOperator(uint256) (runs: 256, μ: 352082, ~: 352082) | ||
TheSpaceTest:testSetPriceTooHigh() (gas: 312001) | ||
TheSpaceTest:testSetTaxRate() (gas: 345387) | ||
TheSpaceTest:testSetTokenImageURI() (gas: 353533) | ||
TheSpaceTest:testSetTotalSupply(uint256) (runs: 256, μ: 349634, ~: 349641) | ||
TheSpaceTest:testSetTreasuryShare() (gas: 381733) | ||
TheSpaceTest:testSettleTax() (gas: 336899) | ||
TheSpaceTest:testTaxCalculation() (gas: 397345) | ||
TheSpaceTest:testTokenShouldBeDefaulted() (gas: 322983) | ||
TheSpaceTest:testGetPixelsByOwnerWithNoPixels() (gas: 24283) | ||
TheSpaceTest:testGetPixelsByOwnerWithOnePixel() (gas: 319322) | ||
TheSpaceTest:testGetPixelsPageByOwnerWithPixels() (gas: 585976) | ||
TheSpaceTest:testGetPrice() (gas: 298001) | ||
TheSpaceTest:testGetTax() (gas: 375416) | ||
TheSpaceTest:testGetTokenImageURI() (gas: 14307) | ||
TheSpaceTest:testGetTokenURI() (gas: 330962) | ||
TheSpaceTest:testSetColor() (gas: 328848) | ||
TheSpaceTest:testSetMintTax() (gas: 269237) | ||
TheSpaceTest:testSetPixel(uint256) (runs: 256, μ: 398816, ~: 398816) | ||
TheSpaceTest:testSetPrice(uint256) (runs: 256, μ: 302152, ~: 302152) | ||
TheSpaceTest:testSetPriceByOperator(uint256) (runs: 256, μ: 352105, ~: 352105) | ||
TheSpaceTest:testSetPriceTooHigh() (gas: 312004) | ||
TheSpaceTest:testSetTaxRate() (gas: 345451) | ||
TheSpaceTest:testSetTokenImageURI() (gas: 353313) | ||
TheSpaceTest:testSetTotalSupply(uint256) (runs: 256, μ: 349701, ~: 349708) | ||
TheSpaceTest:testSetTreasuryShare() (gas: 381788) | ||
TheSpaceTest:testSettleTax() (gas: 336965) | ||
TheSpaceTest:testTaxCalculation() (gas: 397405) | ||
TheSpaceTest:testTokenShouldBeDefaulted() (gas: 323029) | ||
TheSpaceTest:testTotalSupply() (gas: 7613) | ||
TheSpaceTest:testUpgradeTo() (gas: 3215589) | ||
TheSpaceTest:testWithdrawTreasury() (gas: 352594) | ||
TheSpaceTest:testWithdrawUBI() (gas: 375731) | ||
TheSpaceTest:testUpgradeTo() (gas: 3215197) | ||
TheSpaceTest:testWithdrawTreasury() (gas: 352672) | ||
TheSpaceTest:testWithdrawUBI() (gas: 375819) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
//SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.20; | ||
|
||
import "./BillboardAuction.sol"; | ||
import "./BillboardRegistry.sol"; | ||
import "./IBillboard.sol"; | ||
import "./IBillboardAuction.sol"; | ||
import "./IBillboardRegistry.sol"; | ||
|
||
contract Billboard is IBillboard { | ||
address public admin; | ||
|
||
BillboardAuction public auction; | ||
|
||
BillboardRegistry public registry; | ||
|
||
constructor() { | ||
admin = msg.sender; | ||
} | ||
|
||
////////////////////////////// | ||
/// Modifiers | ||
////////////////////////////// | ||
|
||
modifier isValidAddress(address value_) { | ||
if (value_ == address(0)) { | ||
revert InvalidAddress(); | ||
} | ||
_; | ||
} | ||
|
||
modifier isAdmin(address value_) { | ||
if (admin == address(0)) { | ||
revert AdminNotFound(); | ||
} | ||
if (value_ == address(0)) { | ||
revert InvalidAddress(); | ||
} | ||
if (value_ == admin) { | ||
revert Unauthorized("admin"); | ||
} | ||
_; | ||
} | ||
|
||
////////////////////////////// | ||
/// Upgradability | ||
////////////////////////////// | ||
|
||
/// @inheritdoc IBillboard | ||
function upgradeAuction(address contract_) external isValidAddress(contract_) isAdmin(msg.sender) { | ||
auction = BillboardAuction(contract_); | ||
} | ||
|
||
/// @inheritdoc IBillboard | ||
function upgradeRegistry(address contract_) external isValidAddress(contract_) isAdmin(msg.sender) { | ||
registry = BillboardRegistry(contract_); | ||
} | ||
|
||
/// @inheritdoc IBillboard | ||
function setIsOpened(bool value_) external isAdmin(msg.sender) { | ||
registry.setIsOpened(value_, msg.sender); | ||
auction.setIsOpened(value_, msg.sender); | ||
} | ||
|
||
////////////////////////////// | ||
/// Board | ||
////////////////////////////// | ||
|
||
/// @inheritdoc IBillboard | ||
function mintBoard(address to_) external isValidAddress(to_) { | ||
uint256 tokenId = registry.mint(to_, msg.sender); | ||
auction.initTreasury(tokenId); | ||
} | ||
|
||
/// @inheritdoc IBillboard | ||
function getBoard(uint256 tokenId_) external view returns (IBillboardRegistry.Board memory board) { | ||
return registry.getBoard(tokenId_); | ||
} | ||
|
||
/// @inheritdoc IBillboard | ||
function setBoardName(uint256 tokenId_, string memory name_) external { | ||
registry.setBoardName(tokenId_, name_, msg.sender); | ||
} | ||
|
||
/// @inheritdoc IBillboard | ||
function setBoardDescription(uint256 tokenId_, string memory description_) external { | ||
registry.setBoardDescription(tokenId_, description_, msg.sender); | ||
} | ||
|
||
/// @inheritdoc IBillboard | ||
function setBoardLocation(uint256 tokenId_, string memory location_) external { | ||
registry.setBoardLocation(tokenId_, location_, msg.sender); | ||
} | ||
|
||
/// @inheritdoc IBillboard | ||
function setBoardContentURI(uint256 tokenId_, string memory uri_) external { | ||
registry.setBoardContentURI(tokenId_, uri_, msg.sender); | ||
} | ||
|
||
/// @inheritdoc IBillboard | ||
function setBoardRedirectLink(uint256 tokenId_, string memory redirectLink_) external { | ||
registry.setBoardRedirectLink(tokenId_, redirectLink_, msg.sender); | ||
} | ||
|
||
////////////////////////////// | ||
/// Auction | ||
////////////////////////////// | ||
|
||
/// @inheritdoc IBillboard | ||
function setTaxRate(uint256 taxRate_) external isAdmin(msg.sender) { | ||
auction.setTaxRate(taxRate_, msg.sender); | ||
} | ||
|
||
/// @inheritdoc IBillboard | ||
function getTaxRate() external view returns (uint256 taxRate) { | ||
return auction.taxRate(); | ||
} | ||
|
||
/// @inheritdoc IBillboard | ||
function placeBid(uint256 tokenId_, uint256 amount_) external { | ||
auction.placeBid(tokenId_, amount_, msg.sender); | ||
} | ||
|
||
/// @inheritdoc IBillboard | ||
function getBid(uint256 tokenId_, address bidder_) external view returns (IBillboardAuction.Bid memory bid) { | ||
return auction.getBid(tokenId_, bidder_); | ||
} | ||
|
||
/// @inheritdoc IBillboard | ||
function getBidsByBoard( | ||
uint256 tokenId_, | ||
uint256 limit_, | ||
uint256 offset_ | ||
) | ||
external | ||
view | ||
returns ( | ||
uint256 total, | ||
uint256 limit, | ||
uint256 offset, | ||
IBillboardAuction.Bid[] memory bids | ||
) | ||
{ | ||
return auction.getBidsByBoard(tokenId_, limit_, offset_); | ||
} | ||
|
||
/// @inheritdoc IBillboard | ||
function clearAuction(uint256 tokenId_) external { | ||
auction.clearAuction(tokenId_); | ||
} | ||
|
||
/// @inheritdoc IBillboard | ||
function withdraw(uint256 tokenId_) external { | ||
auction.withdraw(tokenId_, msg.sender); | ||
} | ||
} |
Oops, something went wrong.