Skip to content
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
12 changes: 6 additions & 6 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[submodule "moda-contracts/lib/forge-std"]
path = moda-contracts/lib/forge-std
[submodule "contracts/lib/forge-std"]
path = contracts/lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "moda-contracts/lib/openzeppelin-contracts-upgradeable"]
path = moda-contracts/lib/openzeppelin-contracts-upgradeable
[submodule "contracts/lib/openzeppelin-contracts-upgradeable"]
path = contracts/lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
[submodule "moda-contracts/lib/openzeppelin-foundry-upgrades"]
path = moda-contracts/lib/openzeppelin-foundry-upgrades
[submodule "contracts/lib/openzeppelin-foundry-upgrades"]
path = contracts/lib/openzeppelin-foundry-upgrades
url = https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright 2023 MODA Foundation
Copyright 2024 DROPcmdk

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
56 changes: 12 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,4 @@
<div align="center">
<img src="./logo.svg" alt="Logo" height="60" />
<br/>
<br/>
<a href="https://www.npmjs.com/package/modadao">
<img src="https://img.shields.io/npm/v/modadao?style=flat&label=Version" />
</a>
<br/>
<p>A web3 protocol for distributing music on EVM chains.</p>

[![k1]][k2]

[k1]: https://img.shields.io/twitter/follow/moda_dao?style=flat
[k2]: https://x.com/MODA_DAO
</div>


## Getting Started

Expand All @@ -23,53 +9,35 @@ pnpm i

2. Set up environment variables
```bash
cp ./moda-contracts/.env-local ./moda-contracts/.env
# Add your values to ./moda-contracts/.env
cp ./contracts/.env-local ./contracts/.env
# Add your values to ./contracts/.env
```

## Generate Smart Contract Documentation

1. `pnpm c:docs`
2. Visit [localhost:8080](localhost:8080)

### Deploy Membership
### Membership //TODO

Membership is a way to control who has access to your Catalog. The default implementation defines any address as a "member", which means anyone can register tracks in the Catalog. You can extend this logic to define your own rules such as NFT-gates, minimal ERC-20 balance amounts, or a generic whitelist. See Membership.sol in `./moda-contracts/src/Membership.sol`
Membership is a way to control who has access to your Registry. The default implementation defines any address as a "member", which means anyone can register tracks in the Catalog. You can extend this logic to define your own rules such as NFT-gates, minimal ERC-20 balance amounts, or a generic whitelist. See Membership.sol in `./contracts/src/Membership.sol`

1. Deploy contract `pnpm 1_deploy_Membership --chain mumbai`

### Deploy Catalog

2. Deploy contract `pnpm 2_deploy_Catalog --chain mumbai --sender <YOUR_OWNER_ADDRESS>`

Then look in the console for your Catalog address:

```
$ Your Catalog was deployed to:
$ <ADDRESS>
```
### Registry

## (Optional, but not recommended) Deploy Common-Good Contracts
#### Technical Overview

These contracts have already been deployed on Mumbai. It is recommended that you use the ones already deployed so that the creators can benefit, but if you need to change certain features you are free to redeploy these. If you would like these contracts on a particular chain please reach out to the team and we will help facilitate.
The Registry is an upgradeable contract and the only one in the protocol. It follows an Upgradeable Beacon pattern in which a Beacon contract containing the the implementation address is deployed and controlled by an Authorized account. Any proxy that is deployed will refer to this Beacon contract for the implementation address.

### Deploy Registry
`pnpm c:deploy_Registry --chain mumbai`
The Registry uses a Namespaced Storage Layout defined in [ERC-7201](https://eips.ethereum.org/EIPS/eip-7201)

### Deploy Profile
`pnpm c:deploy_Profile --chain mumbai`
The [Foundry Upgrades](https://docs.openzeppelin.com/upgrades-plugins/1.x/api-foundry-upgrades) library is used for ease of upgradeable contract deployment and customizable upgrade safety validations.

### Deploy Management
`pnpm c:deploy_Management --chain mumbai`

### Deploy Splits Factory
`pnpm c:deploy_SplitsFactory --chain mumbai`

### Deploy CatalogFactory
`pnpm c:deploy_CatalogFactory --chain mumbai`

### Register Contracts with Registry
`pnpm c:set_OfficialContracts --chain mumbai --sender <public address of who deployed the Registry>`


## Automatic track verification
Expand All @@ -88,7 +56,7 @@ All registered tracks have a status that is used to represent their authenticity

## Smart Contract Testing

Navigate to the moda-contracts directory and run
Navigate to the contracts directory and run

```bash
pnpm test
Expand All @@ -102,7 +70,7 @@ pnpm coverage

## License

`moda-protocol` is [Apache licensed](LICENSE).
`drop-protocol` is [Apache licensed](LICENSE).

## Contributing

Expand Down
12 changes: 6 additions & 6 deletions apps/dapp/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'drops.moda.audio',
pathname: '/ipfs/*',
protocol: "https",
hostname: "", //TODO
pathname: "/ipfs/*",
},
{
protocol: 'https',
hostname: 'gateway.pinata.cloud',
pathname: '/ipfs/*',
protocol: "https",
hostname: "gateway.pinata.cloud",
pathname: "/ipfs/*",
},
],
},
Expand Down
14 changes: 8 additions & 6 deletions moda-contracts/.env.example → contracts/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@
# DEVELOPER CONFIG - Change these to match your organization values
# =================================================================
DEPLOYER_PRIVATE_KEY=SECRET
EVM_RPC_URL=https://polygon-mumbai.g.alchemy.com/v2/<YOUR_API_KEY>
EVM_RPC_URL=
TESTNET_RPC_URL=

# Etherscan or Polygonscan API Key
ETHERSCAN_API_KEY=SECRET

# Change the catalog to your organization name.
CATALOG_NAME="DRIP"
# Once deployed add your Catalog address here.
CATALOG_ADDRESS=<0xCatalogAddress...>
# USDC Address
USDC_ADDRESS=0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238 # Sepolia

# Once deployed add your Registry address here.
REGISTRY_ADDRESS=<0xRegistryAddress...>

# OpenReleases Contract (Optional & Recommended) - Organizations can deploy a common good Releases contract for artists and
# labels to release tracks without the need of deploying their own Releases contract.
Expand All @@ -26,7 +28,7 @@ TREASURY_ADDRESS=0x01...
# Change this to the address on your chain if you are deploying common good contracts.
# See: https://docs.splits.org/core/split#addresses

SPLIT_MAIN_ADDRESS=0x2ed6c4B5dA6378c7897AC67Ba9e43102Feb694EE # Mumbai
SPLIT_MAIN_ADDRESS=0x54E4a6014D36c381fC43b7E24A1492F556139a6F # Sepolia

# =================================================================
=======
163 changes: 163 additions & 0 deletions contracts/.gas-snapshot
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
MarketplaceTest:test_constructor() (gas: 10761)
MarketplaceTest:test_createSale() (gas: 432806)
MarketplaceTest:test_createSale_RevertIf_Releases_is_not_registered() (gas: 49023)
MarketplaceTest:test_createSale_RevertIf_amountTotal_is_zero() (gas: 49057)
MarketplaceTest:test_createSale_RevertIf_beneficiary_address_is_zero() (gas: 49090)
MarketplaceTest:test_createSale_RevertIf_maxCountPerWallet_is_zero() (gas: 49213)
MarketplaceTest:test_createSale_RevertIf_startAt_is_after_endAt() (gas: 47607)
MarketplaceTest:test_createSale_emits_event() (gas: 426522)
MarketplaceTest:test_purchase() (gas: 600636)
MarketplaceTest:test_purchase_RevertIf_Sale_has_ended() (gas: 432092)
MarketplaceTest:test_purchase_RevertIf_Sale_has_not_started() (gas: 433422)
MarketplaceTest:test_purchase_RevertIf_maxCountPerWallet_is_exceeded() (gas: 594112)
MarketplaceTest:test_purchase_RevertIf_tokenAmount_is_greater_than_amountRemaining() (gas: 435268)
MarketplaceTest:test_purchase_RevertIf_tokenAmount_is_zero() (gas: 434655)
MarketplaceTest:test_purchase_emits_event() (gas: 588888)
MarketplaceTest:test_withdraw() (gas: 450701)
OpenReleasesFactoryTest:test_constructor() (gas: 14921)
OpenReleasesFactoryTest:test_create() (gas: 289818)
OpenReleasesTest:test_burn_emits_event() (gas: 990909)
OpenReleasesTest:test_constructor() (gas: 29107)
OpenReleasesTest:test_create_RevertIf_caller_is_not_track_owner() (gas: 588877)
OpenReleasesTest:test_create_RevertIf_royalty_amount_is_over_2000() (gas: 595969)
OpenReleasesTest:test_create_emits_event() (gas: 1076025)
OpenReleasesTest:test_create_release() (gas: 1100692)
OpenReleasesTest:test_removeRelease() (gas: 993576)
OpenReleasesTest:test_royaltyInfo() (gas: 1079364)
OpenReleasesTest:test_setUri() (gas: 1083522)
OpenReleasesTest:test_setUri_RevertIf_caller_is_not_release_owner() (gas: 1077540)
OpenReleasesTest:test_setUri_RevertIf_tokenId_is_invalid() (gas: 1077380)
OpenReleasesTest:test_setUri_emits_event() (gas: 1082455)
OpenReleasesTest:test_supportsInterface() (gas: 8539)
ProfileTest:test_accountUri() (gas: 109271)
ProfileTest:test_accountUri_reverts_with_nonexistent_profile() (gas: 17082)
ProfileTest:test_approve_reverts() (gas: 10759)
ProfileTest:test_balanceOf_with_profile() (gas: 106209)
ProfileTest:test_balanceOf_without_profile() (gas: 10017)
ProfileTest:test_canMintFor_as_IAccessControl_DEFAULT_ADMIN_ROLE() (gas: 278295)
ProfileTest:test_canMintFor_as_owner() (gas: 92572)
ProfileTest:test_canMintFor_without_DEFAULT_ADMIN_ROLE() (gas: 282304)
ProfileTest:test_canMintFor_without_ownership() (gas: 95031)
ProfileTest:test_constructor() (gas: 19907)
ProfileTest:test_getApproved_reverts() (gas: 8611)
ProfileTest:test_isApprovedForAll() (gas: 10196)
ProfileTest:test_mintFor_as_IAccessControl_DEFAULT_ADMIN_ROLE() (gas: 387396)
ProfileTest:test_mintFor_as_owner() (gas: 201768)
ProfileTest:test_mintFor_emits_events() (gas: 195491)
ProfileTest:test_mintFor_increments_total_supply() (gas: 266038)
ProfileTest:test_mintFor_reverts_for_duplicates() (gas: 198767)
ProfileTest:test_mintFor_without_DEFAULT_ADMIN_ROLE() (gas: 288527)
ProfileTest:test_mintFor_without_ownership() (gas: 101186)
ProfileTest:test_mint_creates_new_token() (gas: 115503)
ProfileTest:test_mint_emits_event() (gas: 107567)
ProfileTest:test_mint_increments_total_supply() (gas: 182489)
ProfileTest:test_mint_reverts_for_duplicates() (gas: 104163)
ProfileTest:test_name() (gas: 12348)
ProfileTest:test_ownerOf() (gas: 106412)
ProfileTest:test_ownerOf_reverts_with_nonexistent_token() (gas: 10708)
ProfileTest:test_returns_false_for_unsupported_interfaces() (gas: 5988)
ProfileTest:test_safeTransferFrom_reverts() (gas: 12946)
ProfileTest:test_safeTransferFrom_with_data_arg_reverts() (gas: 13585)
ProfileTest:test_setApprovalForAll_reverts() (gas: 10805)
ProfileTest:test_supports_ERC165() (gas: 5969)
ProfileTest:test_supports_IERC165() (gas: 5971)
ProfileTest:test_supports_IERC4906() (gas: 5957)
ProfileTest:test_supports_IERC721() (gas: 5880)
ProfileTest:test_supports_IERC721Metadata() (gas: 5895)
ProfileTest:test_supports_IProfile() (gas: 5891)
ProfileTest:test_symbol() (gas: 12390)
ProfileTest:test_tokenUri() (gas: 108898)
ProfileTest:test_tokenUri_reverts_with_nonexistent_token() (gas: 12764)
ProfileTest:test_totalSupply_returns_the_token_count() (gas: 101291)
ProfileTest:test_transferFrom_reverts() (gas: 12954)
ProfileTest:test_updateProfileFor_emits_events() (gas: 391007)
ProfileTest:test_updateProfileFor_reverts_for_nonexisting_profile() (gas: 286741)
ProfileTest:test_updateProfileFor_reverts_when_unauthorized() (gas: 391805)
ProfileTest:test_updateProfileFor_with_AccessControl_DEFAULT_ADMIN_ROLE() (gas: 401956)
ProfileTest:test_updateProfileFor_with_ownership_sets_new_uri() (gas: 215621)
ProfileTest:test_updateProfile_emits_MetadataUpdate() (gas: 108851)
ProfileTest:test_updateProfile_reverts_for_nonexisting_profile() (gas: 13255)
ProfileTest:test_updateProfile_sets_new_uri() (gas: 126727)
RegisterReleaseTest:test_getReleaseTracks() (gas: 426539)
RegisterReleaseTest:test_registerRelease_RevertIf_release_duplicate() (gas: 715756)
RegisterReleaseTest:test_registerRelease_RevertIf_releases_contract_has_no_approval() (gas: 410240)
RegisterReleaseTest:test_registerRelease_RevertIf_releases_contract_not_registered() (gas: 397157)
RegisterReleaseTest:test_registerRelease_RevertIf_track_not_validated() (gas: 471437)
RegisterReleaseTest:test_registerRelease_RevertIf_tracks_unregistered() (gas: 410833)
RegisterReleaseTest:test_registerRelease_emits_event() (gas: 693316)
RegisterReleaseTest:test_registerRelease_with_setReleasesApproval() (gas: 707534)
RegisterReleaseTest:test_registerRelease_with_setReleasesApprovalForAll() (gas: 668860)
RegisterReleaseTest:test_unregisterRelease() (gas: 571904)
RegisterReleaseTest:test_unregisterRelease_emits_event() (gas: 569784)
RegisterReleasesContractTest:test_registerReleasesContract() (gas: 20266)
RegisterReleasesContractTest:test_registerReleasesContract_emits_event() (gas: 134132)
RegisterReleasesContractTest:test_registerReleasesContract_reverts_if_no_releases_registrar_role() (gas: 52701)
RegisterReleasesContractTest:test_registerReleasesContract_reverts_if_releases_contract_already_registered() (gas: 38370)
RegisterReleasesContractTest:test_revert_if_unregistering_unregistered_releases_contract() (gas: 24122)
RegisterReleasesContractTest:test_unregisterReleasesContract() (gas: 28370)
RegisterReleasesContractTest:test_unregisterReleasesContract_emits_event() (gas: 30129)
RegisterTrackTest:test_registerTrack() (gas: 200654)
RegisterTrackTest:test_registerTrack_RevertIf_track_already_registered() (gas: 193313)
RegisterTrackTest:test_registerTrack_RevertIf_user_not_member() (gas: 32188)
RegisterTrackTest:test_registerTrack_emits_event() (gas: 165876)
RegisterTrackTest:test_registerTrack_with_AUTO_VERIFIED_ROLE() (gas: 209434)
RegistryInitializeTest:test_initialize_RevertIf_already_initialized() (gas: 6791331)
RegistryUpgradesTest:test_beacon() (gas: 7489)
RegistryUpgradesTest:test_implementation_address_updated() (gas: 3315989)
RegistryUpgradesTest:test_proxy_can_call_updated_Registry() (gas: 3323900)
ReleasesApprovalTest:test_remove_releases_approval() (gas: 216979)
ReleasesApprovalTest:test_setReleasesApproval() (gas: 227866)
ReleasesApprovalTest:test_setReleasesApprovalForAll() (gas: 223322)
ReleasesApprovalTest:test_setReleasesApprovalForAll_RevertIf_setting_approval_not_artist() (gas: 199177)
ReleasesApprovalTest:test_setReleasesApprovalForAll_RevertIf_setting_approval_with_unregistered_releases_contract() (gas: 194695)
ReleasesApprovalTest:test_setReleasesApprovalForAll_emits_event() (gas: 223173)
ReleasesApprovalTest:test_setReleasesApproval_RevertIf_setting_approval_not_artist() (gas: 200150)
ReleasesApprovalTest:test_setReleasesApproval_RevertIf_setting_approval_with_unregistered_releases_contract() (gas: 198018)
ReleasesApprovalTest:test_setReleasesApproval_emits_event() (gas: 227824)
ReleasesFactoryTest:test_constructor() (gas: 14921)
ReleasesFactoryTest:test_create() (gas: 323542)
ReleasesTest:test_create_RevertIf_caller_is_not_release_admin() (gas: 609395)
ReleasesTest:test_create_RevertIf_royalty_amount_is_over_2000() (gas: 607354)
ReleasesTest:test_create_emits_event() (gas: 1063670)
ReleasesTest:test_create_release_curated() (gas: 1088448)
ReleasesTest:test_initialize() (gas: 26153)
ReleasesTest:test_initialize_RevertIf_already_initialized() (gas: 30475)
ReleasesTest:test_royaltyInfo() (gas: 1067164)
ReleasesTest:test_setUri() (gas: 1073351)
ReleasesTest:test_setUri_RevertIf_tokenId_is_invalid() (gas: 1067464)
ReleasesTest:test_setUri_emits_event() (gas: 1072239)
ReleasesTest:test_supportsInterface() (gas: 8555)
ReleasesTest:test_withdrawRelease() (gas: 1076129)
ReleasesTest:test_withdrawRelease_RevertIf_tokenId_is_invalid() (gas: 1066600)
ReleasesTest:test_withdrawRelease_emits_event() (gas: 1076856)
SetTrackDataTest:test_setTrackBeneficiary() (gas: 212827)
SetTrackDataTest:test_setTrackBeneficiary_RevertIf_not_track_owner() (gas: 200770)
SetTrackDataTest:test_setTrackBeneficiary_RevertIf_track_not_registered() (gas: 24712)
SetTrackDataTest:test_setTrackBeneficiary_emits_event() (gas: 209071)
SetTrackDataTest:test_setTrackFingerprintHash() (gas: 235072)
SetTrackDataTest:test_setTrackFingerprintHash_RevertIf_not_track_owner() (gas: 201252)
SetTrackDataTest:test_setTrackFingerprintHash_RevertIf_track_not_registered() (gas: 25151)
SetTrackDataTest:test_setTrackFingerprintHash_emits_event() (gas: 227870)
SetTrackDataTest:test_setTrackMetadata() (gas: 214610)
SetTrackDataTest:test_setTrackMetadata_RevertIf_not_track_owner() (gas: 201210)
SetTrackDataTest:test_setTrackMetadata_RevertIf_track_not_registered() (gas: 25092)
SetTrackDataTest:test_setTrackMetadata_emits_event() (gas: 206940)
SetTrackDataTest:test_setTrackStatus() (gas: 264320)
SetTrackDataTest:test_setTrackStatus_RevertIf_no_verifier_role() (gas: 195144)
SetTrackDataTest:test_setTrackStatus_RevertIf_track_not_registered() (gas: 56876)
SetTrackDataTest:test_setTrackStatus_emits_event() (gas: 260516)
SetTrackDataTest:test_setTrackValidationHash() (gas: 235202)
SetTrackDataTest:test_setTrackValidationHash_RevertIf_not_track_owner() (gas: 201274)
SetTrackDataTest:test_setTrackValidationHash_RevertIf_track_not_registered() (gas: 25260)
SetTrackDataTest:test_setTrackValidationHash_emits_event() (gas: 227936)
SplitsFactoryTest:test_PERCENTAGE_SCALE() (gas: 5489)
SplitsFactoryTest:test_constructor_sets_sender_as_owner() (gas: 18025)
SplitsFactoryTest:test_create_adds_all_beneficiaries() (gas: 344101)
SplitsFactoryTest:test_create_adds_dust_allocations_to_treasury() (gas: 744589)
SplitsFactoryTest:test_create_emits_SplitCreated() (gas: 342899)
SplitsFactoryTest:test_create_gives_more_shares_to_duplicate_accounts() (gas: 396780)
SplitsFactoryTest:test_create_returns_the_split_address() (gas: 335946)
SplitsFactoryTest:test_create_sets_one_percent_distributor_fee() (gas: 335920)
SplitsFactoryTest:test_create_sorts_unordered_accounts() (gas: 402547)
SplitsFactoryWithForkTest:test_distributeETH_from_SplitMain() (gas: 457027)
SplitsFactoryWithForkTest:test_withdraw_from_splitMain() (gas: 591375)
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 5 additions & 1 deletion moda-contracts/foundry.toml → contracts/foundry.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
[profile.default]
ffi = true
ast = true
src = "src"
out = "out"
libs = ["lib"]
Expand All @@ -10,10 +12,12 @@ remappings = [
'@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/'
]


fs_permissions = [{ access = "read-write", path = "./"}]

[rpc_endpoints]
rpcUrl = "${EVM_RPC_URL}"
rpcUrl = "${TESTNET_RPC_URL}"


[etherscan]
mumbai = { key = "${ETHERSCAN_API_KEY}" }
Expand Down
1 change: 1 addition & 0 deletions contracts/lib/forge-std
Submodule forge-std added at bb4cee
1 change: 1 addition & 0 deletions contracts/lib/openzeppelin-foundry-upgrades
Loading