forked from sourcekeeper_42/sourcekeeper_42-contract-lab
122 lines
3.6 KiB
Solidity
122 lines
3.6 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.19;
|
|
|
|
import "./interfaces/ILabRegistry.sol";
|
|
import "./LabHelper.sol";
|
|
import "@openzeppelin/contracts/access/Ownable.sol";
|
|
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
|
|
|
|
contract LabContract is Ownable, ReentrancyGuard {
|
|
ILabRegistry public labRegistry;
|
|
LabHelper public labHelper;
|
|
|
|
struct ExperimentConfig {
|
|
address creator;
|
|
uint256 startTimestamp;
|
|
uint256 fundingAmount;
|
|
bool isActive;
|
|
bytes32 configHash;
|
|
}
|
|
|
|
mapping(bytes32 => ExperimentConfig) public experiments;
|
|
mapping(address => bytes32[]) public creatorExperiments;
|
|
|
|
event ExperimentCreated(
|
|
bytes32 indexed experimentId,
|
|
address indexed creator,
|
|
uint256 fundingAmount
|
|
);
|
|
|
|
event ExperimentUpdated(
|
|
bytes32 indexed experimentId,
|
|
bool isActive
|
|
);
|
|
|
|
constructor(address _registryAddress, address _helperAddress) {
|
|
require(_registryAddress != address(0), "Invalid registry address");
|
|
require(_helperAddress != address(0), "Invalid helper address");
|
|
|
|
labRegistry = ILabRegistry(_registryAddress);
|
|
labHelper = LabHelper(_helperAddress);
|
|
}
|
|
|
|
function createExperiment(
|
|
uint256 fundingAmount,
|
|
bytes32 configHash
|
|
) external nonReentrant {
|
|
require(fundingAmount > 0, "Funding must be greater than zero");
|
|
require(configHash != bytes32(0), "Invalid config hash");
|
|
|
|
bytes32 experimentId = keccak256(
|
|
abi.encodePacked(msg.sender, block.timestamp, configHash)
|
|
);
|
|
|
|
ExperimentConfig memory newExperiment = ExperimentConfig({
|
|
creator: msg.sender,
|
|
startTimestamp: block.timestamp,
|
|
fundingAmount: fundingAmount,
|
|
isActive: true,
|
|
configHash: configHash
|
|
});
|
|
|
|
experiments[experimentId] = newExperiment;
|
|
creatorExperiments[msg.sender].push(experimentId);
|
|
|
|
require(
|
|
labRegistry.registerExperiment(experimentId, msg.sender),
|
|
"Experiment registration failed"
|
|
);
|
|
|
|
emit ExperimentCreated(experimentId, msg.sender, fundingAmount);
|
|
}
|
|
|
|
function updateExperimentStatus(
|
|
bytes32 experimentId,
|
|
bool newStatus
|
|
) external nonReentrant {
|
|
ExperimentConfig storage experiment = experiments[experimentId];
|
|
|
|
require(
|
|
experiment.creator == msg.sender,
|
|
"Only experiment creator can update status"
|
|
);
|
|
|
|
experiment.isActive = newStatus;
|
|
|
|
emit ExperimentUpdated(experimentId, newStatus);
|
|
}
|
|
|
|
function getExperimentDetails(
|
|
bytes32 experimentId
|
|
) external view returns (ExperimentConfig memory) {
|
|
ExperimentConfig memory experiment = experiments[experimentId];
|
|
|
|
require(
|
|
experiment.creator != address(0),
|
|
"Experiment does not exist"
|
|
);
|
|
|
|
return experiment;
|
|
}
|
|
|
|
function withdrawFunds(
|
|
bytes32 experimentId,
|
|
uint256 amount
|
|
) external nonReentrant {
|
|
ExperimentConfig storage experiment = experiments[experimentId];
|
|
|
|
require(
|
|
experiment.creator == msg.sender,
|
|
"Only experiment creator can withdraw"
|
|
);
|
|
require(experiment.fundingAmount >= amount, "Insufficient funds");
|
|
require(experiment.isActive, "Experiment is not active");
|
|
|
|
experiment.fundingAmount -= amount;
|
|
|
|
(bool success, ) = payable(msg.sender).call{value: amount}("");
|
|
require(success, "Transfer failed");
|
|
}
|
|
|
|
receive() external payable {}
|
|
} |