@artblocks/contracts 1.3.1 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/artifacts/contracts/interfaces/v0.8.x/IPMPV0.sol/IPMPV0.json +7 -1
- package/artifacts/contracts/mock/MockPMPAugmentHook.sol/MockPMPAugmentHook.json +2 -2
- package/artifacts/contracts/mock/MockPMPConfigureHook.sol/MockPMPConfigureHook.json +2 -2
- package/artifacts/contracts/web3call/PMPV0.sol/PMPV0.json +9 -3
- package/artifacts/contracts/web3call/augment-hooks/InjectBaseGasFee.sol/InjectBaseGasFee.json +2 -2
- package/artifacts/contracts/web3call/augment-hooks/InjectChromieSquiggleFloorPrice.sol/InjectChromieSquiggleFloorPrice.json +2 -2
- package/artifacts/contracts/web3call/augment-hooks/InjectIsNounsDaoMember.sol/InjectIsNounsDaoMember.json +2 -2
- package/artifacts/contracts/web3call/augment-hooks/InjectIsProjectFullyMinted.sol/InjectIsProjectFullyMinted.json +2 -2
- package/artifacts/contracts/web3call/augment-hooks/InjectPolyptychTokenHash.sol/InjectPolyptychTokenHash.json +2 -2
- package/artifacts/contracts/web3call/augment-hooks/InjectTokenHashSeed.sol/InjectTokenHashSeed.json +2 -2
- package/artifacts/contracts/web3call/augment-hooks/InjectTokenOwner.sol/InjectTokenOwner.json +2 -2
- package/artifacts/contracts/web3call/augment-hooks/InjectTokenOwnerEthBalance.sol/InjectTokenOwnerEthBalance.json +2 -2
- package/artifacts/contracts/web3call/augment-hooks/InjectUSDCTotalSupply.sol/InjectUSDCTotalSupply.json +2 -2
- package/contracts/interfaces/v0.8.x/IPMPV0.sol +5 -3
- package/contracts/web3call/PMPV0.sol +92 -98
- package/package.json +2 -2
|
@@ -312,6 +312,8 @@ contract PMPV0 is IPMPV0, Web3Call, ReentrancyGuard {
|
|
|
312
312
|
ProjectConfig storage projectConfig = projectConfigs[coreContract][
|
|
313
313
|
ABHelpers.tokenIdToProjectId(tokenId)
|
|
314
314
|
];
|
|
315
|
+
// preallocate memory for auth addresses of each pmpInput
|
|
316
|
+
address[] memory authAddresses = new address[](pmpInputs.length);
|
|
315
317
|
// assign each pmpInput to the token
|
|
316
318
|
// @dev pmpInputs processed sequentially in order of input
|
|
317
319
|
for (uint256 i = 0; i < pmpInputs.length; i++) {
|
|
@@ -322,8 +324,8 @@ contract PMPV0 is IPMPV0, Web3Call, ReentrancyGuard {
|
|
|
322
324
|
];
|
|
323
325
|
PMPConfigStorage storage pmpConfigStorage = projectConfig
|
|
324
326
|
.pmpConfigsStorage[pmpKeyHash];
|
|
325
|
-
// validate pmpInput
|
|
326
|
-
_validatePMPInputAndAuth({
|
|
327
|
+
// validate pmpInput + record the authenticated address used to configure the pmpInput
|
|
328
|
+
authAddresses[i] = _validatePMPInputAndAuth({
|
|
327
329
|
tokenId: tokenId,
|
|
328
330
|
coreContract: coreContract,
|
|
329
331
|
pmpInput: pmpInput,
|
|
@@ -360,7 +362,8 @@ contract PMPV0 is IPMPV0, Web3Call, ReentrancyGuard {
|
|
|
360
362
|
emit TokenParamsConfigured({
|
|
361
363
|
coreContract: coreContract,
|
|
362
364
|
tokenId: tokenId,
|
|
363
|
-
pmpInputs: pmpInputs
|
|
365
|
+
pmpInputs: pmpInputs,
|
|
366
|
+
authAddresses: authAddresses
|
|
364
367
|
});
|
|
365
368
|
}
|
|
366
369
|
|
|
@@ -479,20 +482,19 @@ contract PMPV0 is IPMPV0, Web3Call, ReentrancyGuard {
|
|
|
479
482
|
* @param wallet The wallet address to check.
|
|
480
483
|
* @param coreContract The address of the core contract to call.
|
|
481
484
|
* @param tokenId The tokenId of the token to check.
|
|
482
|
-
* @return
|
|
485
|
+
* @return isTokenOwnerOrDelegate_ True if the wallet is the owner or a delegate of the token,
|
|
483
486
|
* false otherwise.
|
|
484
487
|
*/
|
|
485
488
|
function isTokenOwnerOrDelegate(
|
|
486
489
|
address wallet,
|
|
487
490
|
address coreContract,
|
|
488
491
|
uint256 tokenId
|
|
489
|
-
) external view returns (bool) {
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
});
|
|
492
|
+
) external view returns (bool isTokenOwnerOrDelegate_) {
|
|
493
|
+
(isTokenOwnerOrDelegate_, ) = _isTokenOwnerOrDelegate({
|
|
494
|
+
tokenId: tokenId,
|
|
495
|
+
coreContract: coreContract,
|
|
496
|
+
sender: wallet
|
|
497
|
+
});
|
|
496
498
|
}
|
|
497
499
|
|
|
498
500
|
/**
|
|
@@ -707,6 +709,7 @@ contract PMPV0 is IPMPV0, Web3Call, ReentrancyGuard {
|
|
|
707
709
|
* @param pmpInput The parameter input to validate.
|
|
708
710
|
* @param pmpConfigStorage The project's configuration storage for this parameter.
|
|
709
711
|
* @param projectConfigNonce The project's current configuration nonce.
|
|
712
|
+
* @return permissionedAddress the address used to make the update, accounting for delegation.
|
|
710
713
|
*/
|
|
711
714
|
function _validatePMPInputAndAuth(
|
|
712
715
|
uint256 tokenId,
|
|
@@ -714,7 +717,7 @@ contract PMPV0 is IPMPV0, Web3Call, ReentrancyGuard {
|
|
|
714
717
|
PMPInput memory pmpInput,
|
|
715
718
|
PMPConfigStorage storage pmpConfigStorage,
|
|
716
719
|
uint8 projectConfigNonce
|
|
717
|
-
) internal view {
|
|
720
|
+
) internal view returns (address permissionedAddress) {
|
|
718
721
|
// check that the param is part of the project's most recently configured PMP params
|
|
719
722
|
// @dev use config nonce to check if param is part of most recently configured PMP params
|
|
720
723
|
require(
|
|
@@ -733,88 +736,79 @@ contract PMPV0 is IPMPV0, Web3Call, ReentrancyGuard {
|
|
|
733
736
|
);
|
|
734
737
|
|
|
735
738
|
// ensure caller has appropriate auth
|
|
739
|
+
bool isAuthenticated;
|
|
736
740
|
{
|
|
737
|
-
|
|
741
|
+
AuthOption authOption = pmpConfigStorage.authOption;
|
|
742
|
+
// if artist may configure, check and authenticate if not already authenticated
|
|
743
|
+
if (
|
|
744
|
+
authOption == AuthOption.Artist ||
|
|
745
|
+
authOption == AuthOption.ArtistAndAddress ||
|
|
746
|
+
authOption == AuthOption.ArtistAndTokenOwner ||
|
|
747
|
+
authOption == AuthOption.ArtistAndTokenOwnerAndAddress
|
|
748
|
+
) {
|
|
749
|
+
bool isArtist;
|
|
750
|
+
(isArtist, permissionedAddress) = _isArtist({
|
|
751
|
+
tokenId: tokenId,
|
|
752
|
+
coreContract: coreContract,
|
|
753
|
+
sender: msg.sender
|
|
754
|
+
});
|
|
755
|
+
isAuthenticated = isArtist;
|
|
756
|
+
}
|
|
757
|
+
// if address may configure, check and authenticate if not already authenticated
|
|
758
|
+
if (
|
|
759
|
+
!isAuthenticated &&
|
|
760
|
+
(authOption == AuthOption.Address ||
|
|
761
|
+
authOption == AuthOption.TokenOwnerAndAddress ||
|
|
762
|
+
authOption == AuthOption.ArtistAndAddress ||
|
|
763
|
+
authOption == AuthOption.ArtistAndTokenOwnerAndAddress)
|
|
764
|
+
) {
|
|
765
|
+
permissionedAddress = pmpConfigStorage.authAddress;
|
|
766
|
+
isAuthenticated = permissionedAddress == msg.sender;
|
|
767
|
+
}
|
|
768
|
+
// if token owner or delegate may configure, check and authenticate
|
|
769
|
+
// @dev check token ownerlast to enable pre-mint PMP configuration by non-token-owner
|
|
770
|
+
if (
|
|
771
|
+
!isAuthenticated &&
|
|
772
|
+
(authOption == AuthOption.TokenOwner ||
|
|
773
|
+
authOption == AuthOption.ArtistAndTokenOwner ||
|
|
774
|
+
authOption == AuthOption.TokenOwnerAndAddress ||
|
|
775
|
+
authOption == AuthOption.ArtistAndTokenOwnerAndAddress)
|
|
776
|
+
) {
|
|
777
|
+
bool isTokenOwnerOrDelegate_;
|
|
778
|
+
(
|
|
779
|
+
isTokenOwnerOrDelegate_,
|
|
780
|
+
permissionedAddress
|
|
781
|
+
) = _isTokenOwnerOrDelegate({
|
|
782
|
+
tokenId: tokenId,
|
|
783
|
+
coreContract: coreContract,
|
|
784
|
+
sender: msg.sender
|
|
785
|
+
});
|
|
786
|
+
isAuthenticated = isTokenOwnerOrDelegate_;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
// if not authenticated, revert with appropriate auth error
|
|
790
|
+
if (!isAuthenticated) {
|
|
738
791
|
AuthOption authOption = pmpConfigStorage.authOption;
|
|
739
792
|
if (authOption == AuthOption.Artist) {
|
|
740
|
-
|
|
741
|
-
_isArtist({
|
|
742
|
-
tokenId: tokenId,
|
|
743
|
-
coreContract: coreContract,
|
|
744
|
-
sender: msg.sender
|
|
745
|
-
}),
|
|
746
|
-
"PMP: artist auth required"
|
|
747
|
-
);
|
|
793
|
+
revert("PMP: artist auth required");
|
|
748
794
|
} else if (authOption == AuthOption.TokenOwner) {
|
|
749
|
-
|
|
750
|
-
_isTokenOwnerOrDelegate({
|
|
751
|
-
tokenId: tokenId,
|
|
752
|
-
coreContract: coreContract,
|
|
753
|
-
sender: msg.sender
|
|
754
|
-
}),
|
|
755
|
-
"PMP: token owner auth required"
|
|
756
|
-
);
|
|
795
|
+
revert("PMP: token owner auth required");
|
|
757
796
|
} else if (authOption == AuthOption.ArtistAndTokenOwner) {
|
|
758
|
-
|
|
759
|
-
require(
|
|
760
|
-
_isArtist({
|
|
761
|
-
tokenId: tokenId,
|
|
762
|
-
coreContract: coreContract,
|
|
763
|
-
sender: msg.sender
|
|
764
|
-
}) ||
|
|
765
|
-
_isTokenOwnerOrDelegate({
|
|
766
|
-
tokenId: tokenId,
|
|
767
|
-
coreContract: coreContract,
|
|
768
|
-
sender: msg.sender
|
|
769
|
-
}),
|
|
770
|
-
"PMP: artist and token owner auth required"
|
|
771
|
-
);
|
|
797
|
+
revert("PMP: artist and token owner auth required");
|
|
772
798
|
} else if (authOption == AuthOption.Address) {
|
|
773
|
-
|
|
774
|
-
msg.sender == pmpConfigStorage.authAddress,
|
|
775
|
-
"PMP: address auth required"
|
|
776
|
-
);
|
|
799
|
+
revert("PMP: address auth required");
|
|
777
800
|
} else if (authOption == AuthOption.ArtistAndTokenOwnerAndAddress) {
|
|
778
|
-
|
|
779
|
-
require(
|
|
780
|
-
_isArtist({
|
|
781
|
-
tokenId: tokenId,
|
|
782
|
-
coreContract: coreContract,
|
|
783
|
-
sender: msg.sender
|
|
784
|
-
}) ||
|
|
785
|
-
msg.sender == pmpConfigStorage.authAddress ||
|
|
786
|
-
_isTokenOwnerOrDelegate({
|
|
787
|
-
tokenId: tokenId,
|
|
788
|
-
coreContract: coreContract,
|
|
789
|
-
sender: msg.sender
|
|
790
|
-
}),
|
|
791
|
-
"PMP: artist and token owner and address auth required"
|
|
792
|
-
);
|
|
801
|
+
revert("PMP: artist and token owner and address auth required");
|
|
793
802
|
} else if (authOption == AuthOption.ArtistAndAddress) {
|
|
794
|
-
|
|
795
|
-
_isArtist({
|
|
796
|
-
tokenId: tokenId,
|
|
797
|
-
coreContract: coreContract,
|
|
798
|
-
sender: msg.sender
|
|
799
|
-
}) || msg.sender == pmpConfigStorage.authAddress,
|
|
800
|
-
"PMP: artist and address auth required"
|
|
801
|
-
);
|
|
803
|
+
revert("PMP: artist and address auth required");
|
|
802
804
|
} else if (authOption == AuthOption.TokenOwnerAndAddress) {
|
|
803
|
-
|
|
804
|
-
require(
|
|
805
|
-
msg.sender == pmpConfigStorage.authAddress ||
|
|
806
|
-
_isTokenOwnerOrDelegate({
|
|
807
|
-
tokenId: tokenId,
|
|
808
|
-
coreContract: coreContract,
|
|
809
|
-
sender: msg.sender
|
|
810
|
-
}),
|
|
811
|
-
"PMP: token owner and address auth required"
|
|
812
|
-
);
|
|
805
|
+
revert("PMP: token owner and address auth required");
|
|
813
806
|
} else {
|
|
814
807
|
// @dev no coverage, this should never be reached
|
|
815
808
|
revert("PMP: invalid authOption");
|
|
816
809
|
}
|
|
817
810
|
}
|
|
811
|
+
// @dev auth check is complete
|
|
818
812
|
|
|
819
813
|
// ensure properly configured value
|
|
820
814
|
ParamType paramType = pmpConfigStorage.paramType;
|
|
@@ -875,12 +869,13 @@ contract PMPV0 is IPMPV0, Web3Call, ReentrancyGuard {
|
|
|
875
869
|
// require artist is caller if configuring artist string
|
|
876
870
|
if (pmpInput.configuringArtistString) {
|
|
877
871
|
// require artist is caller
|
|
872
|
+
(bool isArtist, ) = _isArtist({
|
|
873
|
+
tokenId: tokenId,
|
|
874
|
+
coreContract: coreContract,
|
|
875
|
+
sender: msg.sender
|
|
876
|
+
});
|
|
878
877
|
require(
|
|
879
|
-
|
|
880
|
-
tokenId: tokenId,
|
|
881
|
-
coreContract: coreContract,
|
|
882
|
-
sender: msg.sender
|
|
883
|
-
}),
|
|
878
|
+
isArtist,
|
|
884
879
|
"PMP: artist auth required to configure artist string"
|
|
885
880
|
);
|
|
886
881
|
}
|
|
@@ -1020,17 +1015,18 @@ contract PMPV0 is IPMPV0, Web3Call, ReentrancyGuard {
|
|
|
1020
1015
|
* @param tokenId The token ID to get the project ID from.
|
|
1021
1016
|
* @param coreContract The address of the core contract.
|
|
1022
1017
|
* @param sender The address to check if it's the artist.
|
|
1023
|
-
* @return
|
|
1018
|
+
* @return isArtist true if the sender is the artist, false otherwise.
|
|
1019
|
+
* @return artistAddress the address of the artist.
|
|
1024
1020
|
*/
|
|
1025
1021
|
function _isArtist(
|
|
1026
1022
|
uint256 tokenId,
|
|
1027
1023
|
address coreContract,
|
|
1028
1024
|
address sender
|
|
1029
|
-
) internal view returns (bool) {
|
|
1025
|
+
) internal view returns (bool isArtist, address artistAddress) {
|
|
1030
1026
|
uint256 projectId = ABHelpers.tokenIdToProjectId(tokenId);
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1027
|
+
artistAddress = IGenArt721CoreContractV3_Base(coreContract)
|
|
1028
|
+
.projectIdToArtistAddress(projectId);
|
|
1029
|
+
isArtist = artistAddress == sender;
|
|
1034
1030
|
}
|
|
1035
1031
|
|
|
1036
1032
|
/**
|
|
@@ -1041,21 +1037,19 @@ contract PMPV0 is IPMPV0, Web3Call, ReentrancyGuard {
|
|
|
1041
1037
|
* @param tokenId The token ID to check ownership for.
|
|
1042
1038
|
* @param coreContract The address of the core contract.
|
|
1043
1039
|
* @param sender The address to check if it's the token owner.
|
|
1044
|
-
* @return
|
|
1040
|
+
* @return isTokenOwnerOrDelegate_ true if the sender is the token owner or delegate of the token owner, false otherwise.
|
|
1041
|
+
* @return tokenOwner the address of the token owner.
|
|
1045
1042
|
* @dev Always execute within a nonReentrant context.
|
|
1046
1043
|
*/
|
|
1047
1044
|
function _isTokenOwnerOrDelegate(
|
|
1048
1045
|
uint256 tokenId,
|
|
1049
1046
|
address coreContract,
|
|
1050
1047
|
address sender
|
|
1051
|
-
) internal view returns (bool) {
|
|
1048
|
+
) internal view returns (bool isTokenOwnerOrDelegate_, address tokenOwner) {
|
|
1052
1049
|
// @dev leading interaction - only execute within a nonReentrant context
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
}
|
|
1057
|
-
// @dev delegate.xyz v2 support
|
|
1058
|
-
return
|
|
1050
|
+
tokenOwner = IERC721(coreContract).ownerOf(tokenId);
|
|
1051
|
+
isTokenOwnerOrDelegate_ =
|
|
1052
|
+
(tokenOwner == sender) ||
|
|
1059
1053
|
delegateRegistry.checkDelegateForERC721({
|
|
1060
1054
|
to: sender, // hot wallet
|
|
1061
1055
|
from: tokenOwner, // vault
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@artblocks/contracts",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "Smart contracts used by Art Blocks",
|
|
5
5
|
"files": [
|
|
6
6
|
"/contracts/**/*.sol",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"@nomiclabs/hardhat-web3": "^2.0.0",
|
|
91
91
|
"@openzeppelin/hardhat-upgrades": "^1.28.0",
|
|
92
92
|
"@openzeppelin/test-helpers": "^0.5.16",
|
|
93
|
-
"@remix-project/remixd": "^0.6.
|
|
93
|
+
"@remix-project/remixd": "^0.6.46",
|
|
94
94
|
"@safe-global/api-kit": "^1.3.1",
|
|
95
95
|
"@safe-global/protocol-kit": "1.3.0",
|
|
96
96
|
"@safe-global/safe-core-sdk-types": "2.3.0",
|