The first time I audited seriously, I opened the biggest contract in the repo and started reading line one. Two hours later I had a headache and zero findings. I had memorized how the code worked without ever asking what it was supposed to guarantee. That is backwards, and it took me a while to unlearn it.
Now I do not read Solidity first. I read the scope, and before I look at a single function body I write down what must always be true. Bugs are violations of those truths. If you do not know the truths, you are just admiring the code.
Step one: write the invariants before you read
An invariant is a property the protocol claims will always hold, no matter who calls what in what order. For a contest, I start with money and control, because that is where severity lives.
Two questions cover most of it:






