# Security for play-to-earn action game

**URL:** https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926
**Category:** Smart Contracts
**Tags:** erc721, bep20
**Created:** [February 18, 2022, 6:33pm UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926 "2022-02-18T18:33:29Z")
**Posts on this page:** 19
**Page:** 1

<div class="post-metadata">

### Author: ![pmk](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/pmk/32/2097_2.png) [@pmk](https://forum.openzeppelin.com/u/pmk)
#### Post date: [February 18, 2022, 6:33pm UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/1 "2022-02-18T18:33:29Z")

</div>

Hi,

So I'm making a play-to-earn game, that is a web game and its logic runs on the user's machine. After the player finishes a session, the game will call the following mint function:

```auto
contract GoldCoin is ERC20, Ownable, ReentrancyGuard {
    
    uint256 public maxSupply = 200000000 * 10 ** decimals();
    mapping(address => uint256) public canClaimDate;     
    bytes32 private answer = 0x7b2be995daa5546c8be8af8968994a3e99baa3aba4c69818b3abbd9c8a9af88a;    

    constructor() ERC20("Gold Coin", "GC") {
        _mint(msg.sender, 100000000 * 10 ** decimals());
    }

    function mint(uint256 amount, string memory _pass) public nonReentrant{             
        require (amount <= 1000, "suspicious amount detected");        
        require (keccak256(abi.encodePacked(_pass)) == answer, "keyword doesn't match, stop trying to cheat and do some good in the world");
        require (block.timestamp >= canClaimDate[msg.sender], "24 hous haven't passed");
        require (maxSupply < amount + totalSupply(), "max supply exceeded");
        canClaimDate[msg.sender] = block.timestamp + 1 days;
        _mint(msg.sender, amount);
    }         
}

```

What I'm currently doing:

- Limitating the amount of tokens that can be minted in a single function call, to what would be possible by playing.
- Asking for a keyword that will be sent from the game, so it is more difficult to mint directly from the block explorer.
- Limiting the minting to once per day, per player.

I know all this can be circumvented. What other measures would you put in place?  
Passing all the logic through blockchain is not realistic for an action game, only for turn-based games.

Thanks!!!

---

<div class="post-metadata">

### Author: ![coinzep](https://avatars.discourse-cdn.com/v4/letter/c/57b2e6/32.png) [@coinzep](https://forum.openzeppelin.com/u/coinzep)
#### Post date: [June 25, 2022, 10:23am UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/2 "2022-06-25T10:23:54Z")

</div>

have you solved this? wondering the same thing as well because your answer is exposed on the contract!

---

<div class="post-metadata">

### Author: ![Team\_X](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/team_x/32/10471_2.png) [@Team\_X](https://forum.openzeppelin.com/u/Team_X)
#### Post date: [June 25, 2022, 11:31am UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/3 "2022-06-25T11:31:45Z")

</div>

you can use abi.decode to reverse answer. This means \_pass is useless.  
Also the function is public so anyone can get up to 1000 wei per day.  
If the person uses a contract to do this then he can get a lot of tokens fast

---

<div class="post-metadata">

### Author: ![coinzep](https://avatars.discourse-cdn.com/v4/letter/c/57b2e6/32.png) [@coinzep](https://forum.openzeppelin.com/u/coinzep)
#### Post date: [June 25, 2022, 11:52am UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/4 "2022-06-25T11:52:19Z")

</div>

how do games like axie do this though? because players will earn SLP tokens from playing

---

<div class="post-metadata">

### Author: ![Team\_X](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/team_x/32/10471_2.png) [@Team\_X](https://forum.openzeppelin.com/u/Team_X)
#### Post date: [June 25, 2022, 12:03pm UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/5 "2022-06-25T12:03:16Z")

</div>

Well idk but here is an idea of a game maybe it'll help.  
A player can join a game and whenever the game is full (2 players) the server will see that and start the game. After the game was completed the server will call the smart contract and tell the smart contract who won. You can do whitelisted address so that only the server can set the winner. This would be an example but Idk how axie does it

---

<div class="post-metadata">

### Author: ![coinzep](https://avatars.discourse-cdn.com/v4/letter/c/57b2e6/32.png) [@coinzep](https://forum.openzeppelin.com/u/coinzep)
#### Post date: [June 25, 2022, 12:12pm UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/6 "2022-06-25T12:12:51Z")

</div>

i went to axie website. indeed they have a 'visible' main contract for their ERC721 and a 'hidden' contract for claiming rewards

adding @minh_trng as we were just discussing this earlier  
[https://forum.openzeppelin.com/t/games-that-implement-in-game-minting-cant-a-user-simply-mint-items-directly-from-explorer-page](https://forum.openzeppelin.com/t/games-that-implement-in-game-minting-cant-a-user-simply-mint-items-directly-from-explorer-page)

axie website

> **[Smart contracts and GitHub Repo](https://whitepaper.axieinfinity.com/technology/key-smart-contracts)**

claim reward contract (not verified)

> **[Contract Address 0x47340deb65810a1f0d0b1EaE7489d1218c1c150F | Etherscan](https://etherscan.io/address/0x47340deb65810a1f0d0b1EaE7489d1218c1c150F)**
>
> The Contract Address 0x47340deb65810a1f0d0b1EaE7489d1218c1c150F page allows users to view the source code, transactions, balances, and analytics for the contract address. Users can also interact and make transactions to the contract directly on...

do you know how to reverse compile this? curious how they handle rewards here

---

<div class="post-metadata">

### Author: ![coinzep](https://avatars.discourse-cdn.com/v4/letter/c/57b2e6/32.png) [@coinzep](https://forum.openzeppelin.com/u/coinzep)
#### Post date: [June 25, 2022, 12:16pm UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/7 "2022-06-25T12:16:38Z")

</div>

> **[Small Love Potion (SLP) Token Tracker | Etherscan](https://etherscan.io/token/0x37236cd05b34cc79d3715af2383e96dd7443dcf1#readContract)**
>
> Small Love Potion (SLP) Token Tracker on Etherscan shows the price of the Token $0.00, total supply 404,090,637, number of holders 5,725 and updated information of the token. The token tracker page also shows the analytics and historical data.

ok seems like the SLP contract (which is the reward in the game) is totally hidden not even the code is shown!

---

<div class="post-metadata">

### Author: ![Team\_X](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/team_x/32/10471_2.png) [@Team\_X](https://forum.openzeppelin.com/u/Team_X)
#### Post date: [June 25, 2022, 12:17pm UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/8 "2022-06-25T12:17:35Z")

</div>

Sadly not there is a "Decompile Bytecode" function but it probably won't help you a lot. You can go to contract and then there is a orange "Decompile Bytecode" button. The code is sometimes not making a lot of sense and it's looking more like Assembly then solidity.  
Anyways there is no real way to see what's going on. You can just guess.

---

<div class="post-metadata">

### Author: ![coinzep](https://avatars.discourse-cdn.com/v4/letter/c/57b2e6/32.png) [@coinzep](https://forum.openzeppelin.com/u/coinzep)
#### Post date: [June 25, 2022, 12:18pm UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/9 "2022-06-25T12:18:31Z")

</div>

thanks for the input!

---

<div class="post-metadata">

### Author: ![coinzep](https://avatars.discourse-cdn.com/v4/letter/c/57b2e6/32.png) [@coinzep](https://forum.openzeppelin.com/u/coinzep)
#### Post date: [June 25, 2022, 12:18pm UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/10 "2022-06-25T12:18:59Z")

</div>

update  
there's a new SLP contract which does have the solidity code

> **[Axie Infinity: SLP Token | Address 0xcc8fa225d80b9c7d42f96e9570156c65d6caaa25...](https://etherscan.io/address/0xcc8fa225d80b9c7d42f96e9570156c65d6caaa25)**
>
> The Contract Address 0xcc8fa225d80b9c7d42f96e9570156c65d6caaa25 page allows users to view the source code, transactions, balances, and analytics for the contract address. Users can also interact and make transactions to the contract directly on...

---

<div class="post-metadata">

### Author: ![Team\_X](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/team_x/32/10471_2.png) [@Team\_X](https://forum.openzeppelin.com/u/Team_X)
#### Post date: [June 25, 2022, 12:21pm UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/11 "2022-06-25T12:21:39Z")

</div>

yeah but that's just a normal token contract

---

<div class="post-metadata">

### Author: ![coinzep](https://avatars.discourse-cdn.com/v4/letter/c/57b2e6/32.png) [@coinzep](https://forum.openzeppelin.com/u/coinzep)
#### Post date: [June 25, 2022, 12:30pm UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/12 "2022-06-25T12:30:46Z")

</div>

contract SmoothLovePotion is ERC20Detailed, ERC20Mintable, ERC20GatewayWhitelist

seems like they have some custom designs here

---

<div class="post-metadata">

### Author: ![Team\_X](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/team_x/32/10471_2.png) [@Team\_X](https://forum.openzeppelin.com/u/Team_X)
#### Post date: [June 25, 2022, 12:35pm UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/13 "2022-06-25T12:35:21Z")

</div>

yes but still it looks like a pretty normal token other than that

---

<div class="post-metadata">

### Author: ![pmk](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/pmk/32/2097_2.png) [@pmk](https://forum.openzeppelin.com/u/pmk)
#### Post date: [June 27, 2022, 3:50pm UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/14 "2022-06-27T15:50:42Z")

</div>

So the final solution is to not verify the rewards contract, so the password is not visible?

---

<div class="post-metadata">

### Author: ![Team\_X](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/team_x/32/10471_2.png) [@Team\_X](https://forum.openzeppelin.com/u/Team_X)
#### Post date: [June 27, 2022, 7:02pm UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/15 "2022-06-27T19:02:46Z")

</div>

That would work if no one knows the name of the variable.

---

<div class="post-metadata">

### Author: ![minh\_trng](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/minh_trng/32/15370_2.png) [@minh\_trng](https://forum.openzeppelin.com/u/minh_trng)
#### Post date: [June 27, 2022, 10:34pm UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/16 "2022-06-27T22:34:39Z")

</div>

i assume the password would show up in cleartext when you use the "decompile bytecode" button that you mentioned earlier

---

<div class="post-metadata">

### Author: ![pmk](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/pmk/32/2097_2.png) [@pmk](https://forum.openzeppelin.com/u/pmk)
#### Post date: [June 28, 2022, 12:18pm UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/17 "2022-06-28T12:18:11Z")

</div>

But when sending the "claim" transaction on metamask, the function name appears, the parameters it takes, and the hex data. Is this not enough to claim directly on the contract without playing?

---

<div class="post-metadata">

### Author: ![coinzep](https://avatars.discourse-cdn.com/v4/letter/c/57b2e6/32.png) [@coinzep](https://forum.openzeppelin.com/u/coinzep)
#### Post date: [July 17, 2022, 10:12am UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/18 "2022-07-17T10:12:16Z")

</div>

hey everyone wondering how to do this, i have implemented a custom API for my own game and i think it works.

seems to be the safest way to do this. security is on server side (not inside the game) so it is not hackable unless your server is hacked.

you will need NodeJs and ExpressJs (very basic JS) to setup this API

basically the work flow is like this

1. deploy a verify signature contract (standalone contract) which will check that a secret wallet address signed a transaction with a 'secret message'  
reference tutorial: https: // www . youtube . com/watch?v=vYwYe-Gv\_XI

2. in the minting contract for the game item to be minted, it should require a 'true' check from the verify sig contract above before allowing minting

3. now setup a Node app (using ExpressJs + ethers/web3 modules) which is an API app. the API app should accept POST request of a 'secret message' and sign this secret message with the secret wallet private key. (all these are server side so only your hosting provider and you know the private key). (its a POST that doesn't really post since this API app will have no database, but a POST call is more secure from what i understand as the secret message is hidden)

you can also setup custom logic here in the API

1. when user mints something from the game, the game will send a POST request to the API. the game receives the signed transaction, and then feed this to the minting contract which then verifies it.

note: the game app will hold the secret message, but not the secret wallet private key.

the ExpressJs app will hold the private key

---

<div class="post-metadata">

### Author: ![princemeraj](https://avatars.discourse-cdn.com/v4/letter/p/74df32/32.png) [@princemeraj](https://forum.openzeppelin.com/u/princemeraj)
#### Post date: [March 4, 2024, 4:24pm UTC](https://forum.openzeppelin.com/t/security-for-play-to-earn-action-game/24926/20 "2024-03-04T16:24:08Z")

</div>

Considering the real-time nature of your action game, relying solely on blockchain for logic might be impractical, as you mentioned. To further enhance security, maybe you could explore dynamic keyword generation tied to specific in-game events, making it even harder to predict. Also, consider periodic smart contract audits from reputable firms to identify vulnerabilities and ensure the overall robustness of your system. I recently stumbled upon a discussion about "90+ Apps That Pay You Real Money," and someone highlighted the phrase [legit apps that pay instantly](https://wealthofgeeks.com/apps-that-pay-you-money/). It could be worth checking out to see if there's any relevant advice or experiences shared.
