diff --git a/language/04_calling_other_contracts.sol b/language/04_calling_other_contracts.sol new file mode 100644 index 0000000..237bdb5 --- /dev/null +++ b/language/04_calling_other_contracts.sol @@ -0,0 +1,22 @@ +// 1) by creating them +import "../faucet/contracts/Faucet.sol"; + +contract Token is mortal { + Faucet _faucet; + + constructor() { + _faucet = new Faucet(); + _faucet = (new Faucet).value(0.1 ether)(); // Fund it initially + } +} + +// 2) by addressing them + +contract Token2 is mortal { + Faucet _faucet; + + constructor(address faucetAddress) { + _faucet = Faucet(faucetAddress); + _faucet.withdraw(0.1 ether); // can call functions directly + } +} diff --git a/language/05_call_and_delegatecall.txt b/language/05_call_and_delegatecall.txt new file mode 100644 index 0000000..3d41a20 --- /dev/null +++ b/language/05_call_and_delegatecall.txt @@ -0,0 +1,13 @@ +call + - low-level contract function call + - returns boolean. check ! + - no guarantee you are actually calling a contract address + - creates a new msg/context + +delegatecall + - low-level + - executes the given contract function without creating a new msg context + - it has access to caller's state and context (this == caller) + +libraries + - all function calls to libraries are delegatecalls \ No newline at end of file diff --git a/language/06_security_practices.txt b/language/06_security_practices.txt new file mode 100644 index 0000000..572555d --- /dev/null +++ b/language/06_security_practices.txt @@ -0,0 +1,55 @@ +Defensive programming + minimalism: as less LOC as possible + code reuse: use libraries and dont duplicate your local code + code quality: deploying smart contract = launching rocket to space + readability/auditability + test coverage: aim for 100% + +Reentrancy + Vulnerability when a caller contract sends ether to unknown addresses. + A fallback function on the called contract can re-call the caller + + How to deal with it: + 1 - Use built-in transfer function instead of call + 2 - dont be an idiot, first reduce the balance and then send the ether + 3 - use a mutex + +Arithmetic + underflow: unsigned 0 - 1 = a lot + overflow = unsigned a lot + 1 = 0 ; signed a lot + 1 = negative a lot + + solution: use SafeMath from OpenZeppelin + +Unexpected ether + - arises when a contract makes the assumption that any ether received would pass through code (payable function) + - this is not the case. examples: + - selfdestruct receiver: a contract can send another contract ether, and this doesnt call any functions (not even fallback) + - pre-sent ether: address generation is deterministic (creator address + nonce). you can calculate, send ether, then deploy + Solution: + - dont have exact expectations on this.balance + - use a separate variable for received ether. this is not modified by forceful sends + +delegatecall + - it preserves the context and storage slots from the calling contract + - so the called contract can overwrite the caller's state + Measures: + - use the library keyword. forbids state and prevents self-destruct + +Default visibility + - functions are by default public, so double check + +Entropy Illusion + - difficulty to have randomness + - depending on future block variables has the miner tamper issue + approaches: + - for peer-to-peer bet, use commit-reveal technique with stake < block reward + - check ranDAO + +Referencing external contracts + - it is dangerous to pass addresses to external contacts in functions/contructor + - it is better to hardcode their addresses, or create a new instance by deploying it together with the caller contract + +Short address/parameter attack + - when interacting with contracts from outside, you have to form the ABI payload + - addresses are padded with 0 at the end if they are not 20 bytes + - then the ABI can be different than expected if you don't validate the address length externally \ No newline at end of file