EnigmaSimulation

EnigmaSimulation appears in build/enigma_contracts once contracts are migrated.
I would like to get some details on what exactly is EnigmaSimulation’s role.

Right now from what I see, when I make a call to a secret contract that then calls a smart contract, it will do it under EnigmaSimulation’s address.

questions:

  • EnigmaSimulation’s role?
  • Is it unique to every secret contract?
  • Is it safe to use that address, for example: send tokens to it, so then the secret contract can send tokens through a smart contract

Thanks

1 Like

The contract is deployed if your hardware does not support SGX, or you opted to use (SW) Software mode when you init the discovery testnet.
The Enigma contract implements the consensus layer for the Discovery release of the Enigma Protocol; worker registration, deploying secret contracts, creating tasks, selecting workers for a task, deposit/withdraw stake etc.

Hey, thanks for the reply!

If I understand correctly, it is not unique to each secret contract, and thus it is unsafe for somebody to send tokens / ether to it?

There’s 1 contract for the network, can you tell us why you want to send tokens/eth to it?
Your worker/s will send it ENG, and withdraw ENG.

Here’s the contract source for reference

I am working on the non fungible token lottery, the secret contract (lottery) elects a winner at random, and has to call a smart contract (deposit) to send the token to the winner.

The secret contract (lottery) is the authority that decides who receives the token, and when it calls the smart contract (deposit) it is done under one address which is the smart contract "Enigma" (used for consensus etc).

The smart contract (deposit) must implement a security check to make sure that the one who is calling it is the smart contract (Enigma). That is easily done.

However, what stops an attacker from implementing a malicious secret contract that calls the smart contract (deposit) prematurely, since the smart contract (deposit) only checks if its done by the smart contract (Enigma) and has no way of checking whether it came from the secret contract (lottery).

There might be an obvious solution to this so I apologise in advance. Thank you.

FYI I have already implemented the lottery / deposit and it works fine.
But I am not certain it is safe for the reasons stated above.

Actually your user must transfer the token to the contract, not the secret contract.
And the winner will be approved to transfer the token from the contract to their whitelisted address.

From the docs: “Via the same UI, User A sends an NFT (any type) to a smart contract (deposit contract).”

The problem occurs on step 2:

And the winner will be approved to transfer the token from the contract to their whitelisted address.

The one who “approves” is the secret contract, it lets the deposit contract know who is the winner.
This is done by calling a function to the smart contract letting it know who is the winner.

My question is how do we stop a malicious actor from prematurely calling the deposit contract using a malicious secret contract (so it can be done under Enigma’s address) and thus bypass the msg.sender check in the deposit contract.

With you now, you can initially save the sender/lottery address in the contract when you start the lottery and whitelist the accounts, mind you shouldn’t send the addresses to the smart contract but you can call some function there and save your address as lotteryOwner or something.
Later use this to verify it’s the same sender choosing a winner.

Yes indeed, I would like to implement so it doesn’t require the lotteryOwner’s intervention since then the lotteryOwner holds some power on when / where the token is send.

At the end of the day it all boils down to the fact that the secret contract has no unique identity and cannot be distinguished out of the box from any other secret contract in the network.

I am considering into implementing RSA within the secret contract so we can achieve best results.

Hmmm, but it must decide when, based on there being enough participants, and then it must also select a winner.

Hmmm, but it must decide when, based on there being enough participants, and then it must also select a winner.

The secret contract is deciding this, not the lotteryOwner.

The problem with your suggestion above

With you now, you can initially save the sender/lottery address in the contract when you start the lottery and whitelist the accounts, mind you shouldn’t send the addresses to the smart contract but you can call some function there and save your address as lotteryOwner or something.
Later use this to verify it’s the same sender choosing a winner.

is that once the secret contract picks a winner, the lotteryOwner is the one initiating the transfer of the token to the winner, which he could decide not to send the token at all, or send it to a different person other than the winner, thats what I mean with

lotteryOwner holds some power on when / where the token is send

I apologise for making this difficult for you, I don’t believe I am doing a good job making my point.

Ultimately we need to let the smart contract (deposit) know who won the lottery safely and trust-less.
We can work around it by making the lotteryOwner the only one eligible making the call, or we need to implement a RSA solution within the secret contract (lottery) so every call made by the secret contract (lottery) can be checked by the smart contract (deposit).

1 Like

Not a problem at all so no apologies needed, I’m enjoying learning with you :slight_smile:

By picking the winner its only allowing/approving the transfer, the requirement is that “Owner of the winning address is able to withdraw the NFT from the smart contract.”

Agreed, following the instructions will lead us to an implementation which is not 100% trust-less, since the lotteryOwner ultimately is the one saying who can withdraw and not the secret contract.

I have already implemented it according the instructions, but the issue is that its not fully trust-less this way, and I believe it should be done the right way in order to showcase enigma better.

I have asked the team on github if I should follow the instructions eitherway or implement it in a fully trust-less way.

2 Likes

Sorry for the slow responses, the team has been at web3 and dappcon in Berlin this week.
@fredfortier could you take a look at this use case? I know we implemented some encryption in the coinjoin prototype.

@nioni can you clarify how implementing RSA in this contract solves this particular issue? I want to make sure I’m following.
As I understand it, it seems that the problem you describe is that is even an onlyEnigma modifier on the function calling the winner doesn’t prevent someone from calling that function from a different secret contract?

I also think that I may have mis-described the process in the bounty. The secret contract should have the functionality to call a function that automatically sends the NFT to the winner. We don’t have to have the owner withdraw it. This was my own misunderstanding, actually.

I think this example may be interesting (incidentally, it also demonstrates implementing a cryptographic library in the secret contract code, but you may find the aspects around submitting funds to recipient addresses more relevant).

Apologies again for the slow response and the confusion. I hope to be responsive as possible this week and get this to the next stage with you!

As I understand it, it seems that the problem you describe is that is even an onlyEnigma modifier on the function calling the winner doesn’t prevent someone from calling that function from a different secret contract?

Yes!

I also think that I may have mis-described the process in the bounty. The secret contract should have the functionality to call a function that automatically sends the NFT to the winner. We don’t have to have the owner withdraw it. This was my own misunderstanding, actually.

I agree that would be the best.

This library might provide all the functionality I require, I will keep you in the loop.
Thanks and no problem!

hey @nionis!

I was wondering if a way to do this would be to deploy the secret contract first and then pass the SC address into the constructor when deploying the smart contract, with the onlyEnigma() modifier checking against that? Or maybe I’m misunderstanding.

The secret contract address is one which is used for all secret contracts in the network.
So this can be exploited by making a pseudo secret contract and calling the function.

In other words, the secret contract doesn’t have a unique identity.

1 Like