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

allow more function a controller can do on behalf of consumer #422

Merged
merged 3 commits into from
Sep 11, 2024
Merged
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
21 changes: 21 additions & 0 deletions contracts/ConsumerHost.sol
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ contract ConsumerHost is Initializable, OwnableUpgradeable, IConsumer, ERC165, S
/**
* @notice Deposit amount to hosting, consumer can choose approve or not
* @param amount the amount
* @param isApprove approve consumer host agent to act on user's behalf
*/
function deposit(uint256 amount, bool isApprove) external {
require(
Expand All @@ -266,6 +267,26 @@ contract ConsumerHost is Initializable, OwnableUpgradeable, IConsumer, ERC165, S
emit Deposit(msg.sender, amount, consumer.balance);
}

/**
* @notice Deposit amount to hosting, consumer can choose approve or not
* @param _amount the amount
* @param _for account
*/
function depositFor(uint256 _amount, address _for) external {
require(
!(IEraManager(settings.getContractAddress(SQContracts.EraManager)).maintenance()),
'G019'
);
// transfer the balance to contract
IERC20 sqt = IERC20(settings.getContractAddress(SQContracts.SQToken));
sqt.safeTransferFrom(msg.sender, address(this), _amount);

Consumer storage consumer = consumers[_for];
consumer.balance += _amount;

emit Deposit(_for, _amount, consumer.balance);
}

/**
* @notice Withdraw amount to the consumer(sender)
* @param amount the amount
Expand Down
85 changes: 72 additions & 13 deletions contracts/ProjectRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';

import '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol';

import './interfaces/IConsumerRegistry.sol';
import './interfaces/IIndexerRegistry.sol';
import './interfaces/IStaking.sol';
import './interfaces/ISettings.sol';
Expand Down Expand Up @@ -114,6 +115,33 @@ contract ProjectRegistry is
_;
}

/// @dev MODIFIER
/// @notice only consumer or its controller can call
modifier consumerAuthorised(address consumer) {
if (msg.sender != consumer) {
bool isController = IConsumerRegistry(
settings.getContractAddress(SQContracts.ConsumerRegistry)
).isController(consumer, msg.sender);
require(isController, 'PR012');
}

_;
}

/// @dev MODIFIER
/// @notice only consumer or its controller can call
modifier projectAuthorised(uint256 projectId) {
address owner = ownerOf(projectId);
if (msg.sender != owner) {
bool isController = IConsumerRegistry(
settings.getContractAddress(SQContracts.ConsumerRegistry)
).isController(owner, msg.sender);
require(isController, 'PR004');
}

_;
}

/**
* @dev ### FUNCTIONS
* @notice Initialize the contract
Expand Down Expand Up @@ -205,8 +233,37 @@ contract ProjectRegistry is
bytes32 deploymentId,
ProjectType projectType
) external {
_createProject(
projectMetadataUri,
deploymentMetdata,
deploymentId,
projectType,
msg.sender
);
}

/**
* @notice create a project, if in the restrict mode, only creator allowed to call this function
*/
function createProjectFor(
string memory projectMetadataUri,
bytes32 deploymentMetdata,
bytes32 deploymentId,
ProjectType projectType,
address creator
) external consumerAuthorised(creator) {
_createProject(projectMetadataUri, deploymentMetdata, deploymentId, projectType, creator);
}

function _createProject(
string memory projectMetadataUri,
bytes32 deploymentMetdata,
bytes32 deploymentId,
ProjectType projectType,
address creator
) internal {
if (creatorRestricted[projectType]) {
require(creatorWhitelist[msg.sender], 'PR001');
require(creatorWhitelist[creator], 'PR001');
}

require(deploymentInfos[deploymentId].projectId == 0, 'PR003');
Expand All @@ -218,11 +275,11 @@ contract ProjectRegistry is
deploymentInfos[deploymentId] = DeploymentInfo(projectId, deploymentMetdata);

// Mint the corresponding NFT
_safeMint(msg.sender, projectId);
_safeMint(creator, projectId);
_setTokenURI(projectId, projectMetadataUri);

emit ProjectCreated(
msg.sender,
creator,
projectId,
projectMetadataUri,
projectType,
Expand All @@ -234,17 +291,18 @@ contract ProjectRegistry is
/**
* @notice update the Metadata of a project, if in the restrict mode, only creator allowed call this function
*/
function updateProjectMetadata(uint256 projectId, string memory metadataUri) external {
require(ownerOf(projectId) == msg.sender, 'PR004');

function updateProjectMetadata(
uint256 projectId,
string memory metadataUri
) external projectAuthorised(projectId) {
_setTokenURI(projectId, metadataUri);

emit ProjectMetadataUpdated(msg.sender, projectId, metadataUri);
emit ProjectMetadataUpdated(ownerOf(projectId), projectId, metadataUri);
}

function _updateProjectLatestDeployment(uint256 projectId, bytes32 deploymentId) internal {
projectInfos[projectId].latestDeploymentId = deploymentId;
emit ProjectLatestDeploymentUpdated(msg.sender, projectId, deploymentId);
emit ProjectLatestDeploymentUpdated(ownerOf(projectId), projectId, deploymentId);
}

/**
Expand All @@ -255,8 +313,7 @@ contract ProjectRegistry is
bytes32 deploymentId,
bytes32 metadata,
bool updateLatest
) external {
require(ownerOf(projectId) == msg.sender, 'PR004');
) external projectAuthorised(projectId) {
require(deploymentId != bytes32(0) && metadata != bytes32(0), 'PR009');

if (deploymentInfos[deploymentId].projectId == 0) {
Expand All @@ -267,15 +324,17 @@ contract ProjectRegistry is
deploymentInfos[deploymentId].metadata = metadata;
}

emit ProjectDeploymentUpdated(msg.sender, projectId, deploymentId, metadata);
emit ProjectDeploymentUpdated(ownerOf(projectId), projectId, deploymentId, metadata);

if (updateLatest && projectInfos[projectId].latestDeploymentId != deploymentId) {
_updateProjectLatestDeployment(projectId, deploymentId);
}
}

function setProjectLatestDeployment(uint256 projectId, bytes32 deploymentId) external {
require(ownerOf(projectId) == msg.sender, 'PR004');
function setProjectLatestDeployment(
uint256 projectId,
bytes32 deploymentId
) external projectAuthorised(projectId) {
require(deploymentInfos[deploymentId].projectId == projectId, 'PR007');
require(projectInfos[projectId].latestDeploymentId != deploymentId, 'PR010');

Expand Down
44 changes: 35 additions & 9 deletions contracts/RewardsBooster.sol
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,19 @@ contract RewardsBooster is Initializable, OwnableUpgradeable, IRewardsBooster, S
bytes data
);

/// @dev MODIFIER
/// @notice only consumer or its controller can call
modifier consumerAuthorised(address consumer) {
if (msg.sender != consumer) {
bool isController = IConsumerRegistry(
settings.getContractAddress(SQContracts.ConsumerRegistry)
).isController(consumer, msg.sender);
require(isController, 'RB014');
}

_;
}

/**
* @notice ### FUNCTIONS
* @notice Initialize the contract
Expand Down Expand Up @@ -181,7 +194,7 @@ contract RewardsBooster is Initializable, OwnableUpgradeable, IRewardsBooster, S
}

/**
* @notice add booster deployment staking modify eraPool and deployment map
* @notice add booster to a deployment
* @param _deploymentId the deployment id
* @param _amount the added amount
*/
Expand All @@ -198,6 +211,26 @@ contract RewardsBooster is Initializable, OwnableUpgradeable, IRewardsBooster, S
);
}

/**
* @notice add booster to a deployment for a different user
* @param _deploymentId the deployment id
* @param _amount the added amount
* @param _for on behalf of the account boost was added
*/
function boostDeploymentFor(
bytes32 _deploymentId,
uint256 _amount,
address _for
) external consumerAuthorised(_for) onlyRegisteredDeployment(_deploymentId) {
_addBoosterDeployment(_deploymentId, _for, _amount);

IERC20(settings.getContractAddress(SQContracts.SQToken)).safeTransferFrom(
msg.sender,
address(this),
_amount
);
}

/**
* @notice remove booster from deployment
* @param deploymentId deploymentId
Expand All @@ -221,15 +254,8 @@ contract RewardsBooster is Initializable, OwnableUpgradeable, IRewardsBooster, S
bytes32 from,
bytes32 to,
uint256 amount
) external onlyRegisteredDeployment(to) {
) external onlyRegisteredDeployment(to) consumerAuthorised(account) {
require(from != to, 'RB013');
if (account != msg.sender) {
require(
IConsumerRegistry(settings.getContractAddress(SQContracts.ConsumerRegistry))
.isController(account, msg.sender),
'RB014'
);
}

require(deploymentPools[from].accountBooster[account] >= amount, 'RB003');
_removeBoosterDeployment(from, account, amount);
Expand Down
6 changes: 3 additions & 3 deletions contracts/StateChannel.sol
Original file line number Diff line number Diff line change
Expand Up @@ -382,9 +382,9 @@ contract StateChannel is Initializable, OwnableUpgradeable, SQParameter {
bool isIndexer = msg.sender == state.indexer;
bool isConsumer = msg.sender == state.consumer;
if (!isIndexer && !isConsumer) {
address controller;
controller = IIndexerRegistry(settings.getContractAddress(SQContracts.IndexerRegistry))
.getController(state.indexer);
address controller = IIndexerRegistry(
settings.getContractAddress(SQContracts.IndexerRegistry)
).getController(state.indexer);
isIndexer = msg.sender == controller;
}
if (_isContract(state.consumer)) {
Expand Down
18 changes: 18 additions & 0 deletions publish/ABI/ConsumerHost.json
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,24 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "_for",
"type": "address"
}
],
"name": "depositFor",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "disapprove",
Expand Down
33 changes: 33 additions & 0 deletions publish/ABI/ProjectRegistry.json
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,39 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "projectMetadataUri",
"type": "string"
},
{
"internalType": "bytes32",
"name": "deploymentMetdata",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "deploymentId",
"type": "bytes32"
},
{
"internalType": "enum ProjectType",
"name": "projectType",
"type": "uint8"
},
{
"internalType": "address",
"name": "creator",
"type": "address"
}
],
"name": "createProjectFor",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
Expand Down
23 changes: 23 additions & 0 deletions publish/ABI/RewardsBooster.json
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,29 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "_deploymentId",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "_for",
"type": "address"
}
],
"name": "boostDeploymentFor",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
Expand Down
4 changes: 2 additions & 2 deletions publish/revertcode.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,15 @@
"PR001": "address is not authorised to operate projects",
"PR002": "only status for NOTINDEXING services can be updated",
"PR003": "deployment Id already registered",
"PR004": "invaild owner of the project",
"PR004": "invaild owner of the project or not authorised",
"PR005": "can not stop indexing for NOTINDEXING services",
"PR006": "cannot stop indexing with an ongoing service agreement",
"PR007": "Inconsistent project id and deployment id",
"PR008": "deployment metadata not changed",
"PR009": "deployment id or metadata is empty",
"PR010": "project latest deployment id not changed",
"PR011": "deployment not registered",
"PR012": "Caller is not the controller of runner",
"PR012": "Caller is not the controller",
"RD001": "Waiting Era",
"RD002": "Era expired",
"RD003": "Waiting next era",
Expand Down
Loading
Loading