Skip to main content

RegenStakerFactory

Git Source

Title: RegenStaker Factory

Author: Golem Foundation

Deploys RegenStaker contracts with explicit variant selection

SECURITY: Validates deployment bytecode against pre-configured canonical hashes

SECURITY ASSUMPTION: Factory deployer is trusted to provide correct canonical bytecode hashes. If deployer is compromised, all future deployments could use unauthorized code. This is an acceptable risk given the controlled deployment environment.

TRUST BOUNDARY WARNING: This factory guarantees CODE IDENTITY only, NOT parameter safety. The factory validates that deployed bytecode matches canonical, audited code. However, it does NOT validate constructor parameters, including:

  • earningPowerCalculator: Controls reward distribution logic
  • admin: Has full control over staker configuration
  • Access Control: Allowsets and blocksets control access to various operations A malicious actor can deploy a staker with canonical bytecode but inject:
  • A malicious earning power calculator (to manipulate rewards)
  • Themselves as admin (to change calculator post-deployment)
  • Malicious address sets

OPERATIONAL SECURITY: Before funding or integrating with ANY RegenStaker instance:

  1. Verify the earningPowerCalculator address and its code
  2. Verify the admin is a trusted party/governance contract
  3. Verify all address sets are legitimate
  4. For official deployments, use published addresses from governance The StakerDeploy event includes calculator address and codehash to facilitate verification. For production use, consider requiring deployments from a governance-approved strict factory that maintains an allowset of acceptable calculators.

Note: security-contact: [email protected]

State Variables

canonicalBytecodeHash

mapping(RegenStakerVariant => bytes32) public canonicalBytecodeHash

stakers

Tracks deployed stakers per deployer

mapping(address => StakerInfo[]) public stakers

Functions

constructor

Initializes the factory with canonical bytecode hashes for both variants

constructor(bytes32 regenStakerBytecodeHash, bytes32 noDelegationBytecodeHash) ;

Parameters

NameTypeDescription
regenStakerBytecodeHashbytes32Canonical hash for WITH_DELEGATION variant
noDelegationBytecodeHashbytes32Canonical hash for WITHOUT_DELEGATION variant

validatedBytecode

Modifier to validate bytecode against canonical hash

modifier validatedBytecode(bytes calldata code, RegenStakerVariant variant) ;

createStakerWithoutDelegation

Deploy RegenStaker without delegation support

WARNING: This factory validates bytecode but NOT constructor parameters. Verify params.earningPowerCalculator, params.admin, and address sets before funding!

function createStakerWithoutDelegation(CreateStakerParams calldata params, bytes32 salt, bytes calldata code)
external
validatedBytecode(code, RegenStakerVariant.WITHOUT_DELEGATION)
returns (address stakerAddress);

Parameters

NameTypeDescription
paramsCreateStakerParamsStaker configuration parameters
saltbytes32Deployment salt for deterministic addressing
codebytesBytecode for WITHOUT_DELEGATION variant

Returns

NameTypeDescription
stakerAddressaddressAddress of deployed contract

createStakerWithDelegation

Deploy RegenStaker with delegation support

WARNING: This factory validates bytecode but NOT constructor parameters. Verify params.earningPowerCalculator, params.admin, and address sets before funding!

function createStakerWithDelegation(CreateStakerParams calldata params, bytes32 salt, bytes calldata code)
external
validatedBytecode(code, RegenStakerVariant.WITH_DELEGATION)
returns (address stakerAddress);

Parameters

NameTypeDescription
paramsCreateStakerParamsStaker configuration parameters
saltbytes32Deployment salt for deterministic addressing
codebytesBytecode for WITH_DELEGATION variant

Returns

NameTypeDescription
stakerAddressaddressAddress of deployed contract

predictStakerAddress

Predict deterministic deployment address

function predictStakerAddress(bytes32 salt, address deployer, bytes memory bytecode)
external
view
returns (address);

Parameters

NameTypeDescription
saltbytes32Deployment salt
deployeraddressAddress that will deploy
bytecodebytesDeployment bytecode (including constructor args)

Returns

NameTypeDescription
<none>addressPredicted contract address

getStakersByDeployer

Returns all RegenStakers deployed by a specific address

function getStakersByDeployer(address deployer) external view returns (StakerInfo[] memory);

Parameters

NameTypeDescription
deployeraddressDeployer address

_validateBytecode

Validate bytecode against canonical hash

function _validateBytecode(bytes calldata code, RegenStakerVariant variant) internal view;

Parameters

NameTypeDescription
codebytesBytecode to validate
variantRegenStakerVariantRegenStaker variant this bytecode represents

_deployStaker

function _deployStaker(
CreateStakerParams calldata params,
bytes32 salt,
bytes memory code,
RegenStakerVariant variant
) internal returns (address stakerAddress);

_encodeConstructorParams

function _encodeConstructorParams(CreateStakerParams calldata params) internal pure returns (bytes memory);

_recordStaker

function _recordStaker(
CreateStakerParams calldata params,
address stakerAddress,
bytes32 salt,
RegenStakerVariant variant
) internal;

Events

StakerDeploy

Emitted when a new RegenStaker is deployed

calculatorAddress is sufficient for verification; off-chain tools can query code directly

event StakerDeploy(
address indexed deployer,
address indexed admin,
address indexed stakerAddress,
bytes32 salt,
RegenStakerVariant variant,
address calculatorAddress
);

Parameters

NameTypeDescription
deployeraddressAddress that called the factory
adminaddressAdmin of the newly deployed staker
stakerAddressaddressAddress of the deployed staker
saltbytes32Deployment salt used
variantRegenStakerVariantVariant of staker deployed
calculatorAddressaddressEarning power calculator address (CRITICAL FOR VERIFICATION)

Errors

InvalidBytecode

error InvalidBytecode();

UnauthorizedBytecode

error UnauthorizedBytecode(RegenStakerVariant variant, bytes32 providedHash, bytes32 expectedHash);

Structs

CreateStakerParams

struct CreateStakerParams {
IERC20 rewardsToken;
IERC20 stakeToken;
address admin;
IAddressSet stakerAllowset;
IAddressSet stakerBlockset;
AccessMode stakerAccessMode;
IAddressSet allocationMechanismAllowset;
IEarningPowerCalculator earningPowerCalculator;
uint256 maxBumpTip;
uint256 minimumStakeAmount;
uint256 rewardDuration;
}

StakerInfo

Information about a deployed RegenStaker

struct StakerInfo {
address deployerAddress;
uint256 timestamp;
address admin;
address stakerAddress;
RegenStakerVariant variant;
address calculatorAddress;
bytes32 salt;
}

Enums

RegenStakerVariant

enum RegenStakerVariant {
WITHOUT_DELEGATION,
WITH_DELEGATION
}