Skip to content

Commit

Permalink
[TP-2147] Add Gem Game contract (#195)
Browse files Browse the repository at this point in the history
* Feat: add Gem Game contract

* Feat: add block timestamp, add test

* Fix: compiler version

* Housekeeping

* Feat: add status, deployment, to readme

* Feat: add author

* forge install: contract-deployer

* Feat: add deployment script for gem game

* Remove solhint warnings

---------

Co-authored-by: Pano Skylakis <[email protected]>
Co-authored-by: Peter Robinson <[email protected]>
  • Loading branch information
3 people authored Apr 12, 2024
1 parent 98df349 commit 27d6570
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 0 deletions.
21 changes: 21 additions & 0 deletions contracts/games/gems/GemGame.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) Immutable Pty Ltd 2018 - 2024
// SPDX-License-Identifier: Apache 2
pragma solidity ^0.8.19;

/**
* @title GemGame - A simple contract that emits an event for the purpose of indexing off-chain
* @author Immutable
* @dev The GemGame contract is not designed to be upgradeable or extended
*/
contract GemGame {
/// @notice Indicates that an account has earned a gem
event GemEarned(address indexed account, uint256 timestamp);

/**
* @notice Function that emits a `GemEarned` event
*/
function earnGem() external {
// solhint-disable-next-line not-rely-on-time
emit GemEarned(msg.sender, block.timestamp);
}
}
18 changes: 18 additions & 0 deletions contracts/games/gems/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Gem (GM) Game

The GemGame contract emits a single event for the purpose of indexing off-chain.

## Immutable Contract Addresses

| Environment/Network | Deployment Address | Commit Hash |
|--------------------------|--------------------|-------------|
| imtbl-zkevm-testnet | - | - |
| imtbl-zkevm-mainnet | - | - |

# Status

Contract threat models and audits:

| Description | Date |Version Audited | Link to Report |
|---------------------------|------------------|-----------------|----------------|
| Not audited and no threat model | - | - | - |
60 changes: 60 additions & 0 deletions script/games/gems/DeployGemGame.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) Immutable Pty Ltd 2018 - 2023
// SPDX-License-Identifier: Apache-2.0

pragma solidity ^0.8.20;

import "forge-std/Test.sol";
import {GemGame} from "../../../contracts/games/gems/GemGame.sol";

/**
* @title IDeployer Interface
* @notice This interface defines the contract responsible for deploying and optionally initializing new contracts
* via a specified deployment method.
* @dev Credit to axelarnetwork https://github.com/axelarnetwork/axelar-gmp-sdk-solidity/blob/main/contracts/interfaces/IDeployer.sol
*/
interface IDeployer {
function deploy(bytes memory bytecode, bytes32 salt) external payable returns (address deployedAddress_);
function deployAndInit(bytes memory bytecode, bytes32 salt, bytes calldata init)
external
payable
returns (address deployedAddress_);
function deployedAddress(bytes calldata bytecode, address sender, bytes32 salt)
external
view
returns (address deployedAddress_);
}

struct DeploymentArgs {
address signer;
address deployer;
string salt;
}

contract DeployGemGame is Test {
function deploy() external {
address signer = vm.envAddress("DEPLOYER_ADDRESS");
address deployer = vm.envAddress("OWNABLE_CREATE3_FACTORY_ADDRESS");
string memory salt = vm.envString("GEM_GAME_SALT");

DeploymentArgs memory deploymentArgs = DeploymentArgs({signer: signer, deployer: deployer, salt: salt});

_deploy(deploymentArgs);
}

function _deploy(DeploymentArgs memory args) internal returns (GemGame gemGameContract) {
IDeployer ownableCreate3 = IDeployer(args.deployer);

// Create deployment bytecode and encode constructor args
bytes memory bytecode = abi.encodePacked(type(GemGame).creationCode);

bytes32 saltBytes = keccak256(abi.encode(args.salt));

/// @dev Deploy the contract via the Ownable CREATE3 factory
vm.startBroadcast(args.signer);

address gemGameContractAddress = ownableCreate3.deploy(bytecode, saltBytes);
gemGameContract = GemGame(gemGameContractAddress);

vm.stopBroadcast();
}
}
22 changes: 22 additions & 0 deletions test/games/gems/GemGame.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright Immutable Pty Ltd 2018 - 2024
// SPDX-License-Identifier: Apache 2.0
pragma solidity ^0.8.20;

import "forge-std/Test.sol";
import {GemGame} from "../../../contracts/games/gems/GemGame.sol";

contract GemGameTest is Test {
event GemEarned(address indexed account, uint256 timestamp);

GemGame gemGame;

function setUp() public {
gemGame = new GemGame();
}

function testEarnGem_EmitsGemEarnedEvent() public {
vm.expectEmit(true, true, false, false);
emit GemEarned(address(this), block.timestamp);
gemGame.earnGem();
}
}

0 comments on commit 27d6570

Please sign in to comment.